Exemple #1
0
static int 
_pstr_compare(void *privdata, const void *key1,
        const void *key2) {
  (void) privdata;
  pstring *a = (pstring *) key1;
  pstring *b = (pstring *) key2;
  return pstrcmp(a, b) == 0;
}
pbool PImage::save(const pchar *path, POutputStream &os)
{
    // Find the type of image by checking the prefix of the path.
    const pchar* suffix = pstrrchr(path, '.');
    if (pstrcmp(suffix, ".png") == 0)
    {
        return pImagePNGWrite(os, 
                this->width(), this->height(), 
                this->pixelFormat(), this->data());
    }
    else if (pstrcmp(suffix, ".tga") == 0)
    {
        return pImageTGAWrite(os, 
                this->width(), this->height(), 
                this->pixelFormat(), this->data());
    }
    return false;
}
void P_APIENTRY pDebugPrintStack(pint32 skip)
{
    typedef USHORT (WINAPI *CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG);
    CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress(LoadLibrary(TEXT("kernel32.dll")), 
                "RtlCaptureStackBackTrace"));

    if (func == NULL)
    {
        return ; 
    }

    // Quote from Microsoft Documentation:
    // ## Windows Server 2003 and Windows XP:  
    // ## The sum of the FramesToSkip and FramesToCapture parameters must be less than 63.
    const int kMaxCallers = 62; 

    HANDLE hProcess = GetCurrentProcess();
    SymInitialize(hProcess, NULL, TRUE);

    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)malloc(sizeof(SYMBOL_INFO) + 256);
    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    pSymbol->MaxNameLen = 255;
    
    void* callers[kMaxCallers];
    int count = (func)(0, kMaxCallers, callers, NULL);

    // To skip the pDebugPrintStack function frame, we start from 1 instead of 0.
    for(int i = skip; i < count; i++)
    {
        //PLOG_INFO("*** %d called from %016I64LX\n", i, callers[i]);

        DWORD addr = (DWORD)(callers[i]);
        DWORD64 symDisplacement = 0;
        if (SymFromAddr(hProcess, addr, 0, pSymbol))
        {
            IMAGEHLP_LINE lineInfo = {sizeof(IMAGEHLP_LINE)};
            DWORD dwLineDisplacement;

            if (SymGetLineFromAddr(hProcess, addr, &dwLineDisplacement, &lineInfo))
            {
                PLOG_INFO("%s:%s(),Line %u", lineInfo.FileName, pSymbol->Name, lineInfo.LineNumber); 
            }
            
            // Stop the walk at main function. 
            if (pstrcmp(pSymbol->Name, "main") == 0)
            {
                break;
            }
        }
    }
    
    SymCleanup(GetCurrentProcess());
}
Exemple #4
0
static int 
_docref_cmp(void *privdata, const void *key1, const void *key2) {
  Engine *engine = privdata;
  
  DocRef *a = key1;
  DocRef *b = key2;
  
  pstring *pa = a->tmp ? a->tmp : ring_buffer_get_pstring(engine->stream, a->off, a->len);
  pstring *pb = b->tmp ? b->tmp : ring_buffer_get_pstring(engine->stream, b->off, b->len);
  
  return pstrcmp(pa, pb) == 0;
}
pbool PPropertyBool::unpack(const pchar *value)
{
    const pchar *v = pStringTrim(value);
    if (pstrcmp(v, "true") == 0)
    {
        m_value = true;
    }
    else
    {
        m_value = false;
    }

    return true;
}
Exemple #6
0
int
description_read_name (description_t* d,
		       action_desc_t* a,
		       const char* name_begin,
		       const char* name_end)
{
  if (name_end == 0) {
    name_end = name_begin + strlen (name_begin);
  }

  if (buffer_file_seek (&d->bf, 0) != 0) {
    return -1;
  }

  size_t count;
  if (buffer_file_read (&d->bf, &count, sizeof (size_t)) != 0) {
    return -1;
  }

  for (size_t idx = 0; idx != count; ++idx) {
    const action_descriptor_t* ad = buffer_file_readp (&d->bf, sizeof (action_descriptor_t));
    if (ad == 0) {
      return -1;
    }

    const char* name = buffer_file_readp (&d->bf, ad->name_size);
    if (name == 0) {
      return -1;
    }

    const char* description = buffer_file_readp (&d->bf, ad->description_size);
    if (description == 0) {
      return -1;
    }

    if (pstrcmp (name, 0, name_begin, name_end) == 0) {
      a->type = ad->type;
      a->parameter_mode = ad->parameter_mode;
      a->number = ad->number;
      a->name_begin = name;
      a->name_end = name + ad->name_size;
      a->description_begin = description;
      a->description_end = description + ad->description_size;
      return 0;
    }
  }

  return -1;
}
Exemple #7
0
static inode_t*
descend (inode_t* parent,
	 const char* name_begin,
	 const char* name_end)
{
  if (parent->type != DIRECTORY) {
    return 0;
  }

  inode_t* ptr;
  for (ptr = parent->first_child; ptr != 0; ptr = ptr->next_sibling) {
    if (pstrcmp (name_begin, name_end, ptr->name_begin, ptr->name_end) == 0) {
      return ptr;
    }
  }

  return 0;
}
Exemple #8
0
static inode_t*
directory_find_or_create (inode_t* parent,
			  const char* name_begin,
			  const char* name_end)
{
  /* Iterate over the parent's children looking for the name. */
  inode_t** ptr;
  for (ptr = &parent->first_child; *ptr != 0; ptr = &(*ptr)->next_sibling) {
    if (pstrcmp ((*ptr)->name_begin, (*ptr)->name_end, name_begin, name_end) == 0) {
      return *ptr;
    }
  }

  /* Create a node. */
  *ptr = inode_create (DIRECTORY, name_begin, name_end, -1, 0, parent);

  return *ptr;
}
Exemple #9
0
static inode_t*
file_find_or_create (inode_t* parent,
		     const char* name_begin,
		     const char* name_end,
		     bd_t bd,
		     size_t size)
{
  /* Iterate over the parent's children looking for the name. */
  inode_t** ptr;
  for (ptr = &parent->first_child; *ptr != 0; ptr = &(*ptr)->next_sibling) {
    if (pstrcmp ((*ptr)->name_begin, (*ptr)->name_end, name_begin, name_end) == 0) {
      return *ptr;
    }
  }

  /* Create a node. */
  *ptr = inode_create (FILE, name_begin, name_end, bd, size, parent);

  return *ptr;
}
PMaterial *PMaterial::unpack(PXmlElement *element, PResourceManager *resourceManager)
{
    PASSERT(element->isValid());

    PMaterial *ret;
    
    const pchar *idValue = element->attribute("id");
    if (idValue == P_NULL)
    {
        PLOG_ERROR("Failed to find the id of the material in this xml node.");
        return P_NULL;
    }

    ret = PNEW(PMaterial(idValue, resourceManager));

    // Go over all material parameters and set their values.
    puint32 numParameters = ret->numberOfMaterialParameters();
    for (puint32 i = 0; i < numParameters; ++i)
    {
        PMaterialParameter *parameter = ret->materialParameter(i);
        const pchar *parameterValue = element->attribute(parameter->name().c_str());
        if (parameterValue != P_NULL)
        {
            if (!parameter->unpack(parameterValue, resourceManager))
            {
                PLOG_WARNING("Failed to unpack parameter %s in materail %s.", parameterValue, idValue);
            }
        }
    }

	// TODO: validate the matching of type of uniform variable to the type of material parameter.

    const pchar *transparentValue = element->attribute("transparent");
    if (transparentValue != P_NULL && pstrcmp(transparentValue, "true") == 0)
    {
        ret->setTransparent(true);
    }

    return ret;
}
PDir::PDir(const pchar *dir)
{
    // Check if the directory exists.
    DWORD dwAttrib = GetFileAttributesA(dir);
    m_exists = ((dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
    
    // Fetch the item names in that directory.
    WIN32_FIND_DATAA fdFile;
    HANDLE hFind = NULL;

    pchar path[MAX_PATH];

    m_items = P_NULL;
    m_numberOfItems = 0;

    puint32 capacity = 32;
    puint8 *itemData = PNEWARRAY(puint8, capacity * sizeof(PDirItem));
    pmemset(itemData, 0, sizeof(capacity * sizeof(PDirItem)));

    // Specify a file mask. *.* = We want everything!
    psprintf(path, MAX_PATH, "%s\\*.*", dir);

    if ((hFind = FindFirstFileA(path, &fdFile)) == INVALID_HANDLE_VALUE)
    {
        PLOG_ERROR("Failed to read directory %s.", dir);
        PDELETEARRAY(itemData);
    }
    else
    {
        do
        {
            // Find first file will always return "." and ".." 
            // as the first two directories.
            if (pstrcmp(fdFile.cFileName, ".") != 0 && 
                pstrcmp(fdFile.cFileName, "..") != 0)
            {
                //Build up our file path using the passed in
                //  [sDir] and the file/foldername we just found:
                psprintf(path, MAX_PATH, "%s\\%s", dir, fdFile.cFileName);

                //Is the entity a File or Folder?
                if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    // TODO: use the absolute path.
                    new (itemData + m_numberOfItems * sizeof(PDirItem)) PDirItem(P_DIR_ITEM_DIRECTORY, path);
                    m_numberOfItems++;
                }
                else if ((fdFile.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
                         (fdFile.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE))
                {
                    // TODO: use the absolute path.
                    new (itemData + m_numberOfItems * sizeof(PDirItem)) PDirItem(P_DIR_ITEM_FILE, path);
                    m_numberOfItems++;
                }
                else
                {
                    PLOG_WARNING("%s is not seen supported.", path);
                }

                if (m_numberOfItems > capacity)
                {
                    resizeItemArray(itemData, capacity, 2 * capacity);
                    capacity *= 2;
                }
            }
        }
        while (FindNextFileA(hFind, &fdFile)); // Find the next file.

        FindClose(hFind); //Always, Always, clean things up!
    }

    m_items = reinterpret_cast<PDirItem*>(itemData);
}
PDir::PDir(const pchar *dir)
{
    // Check if the directory exists.
    struct stat s;
    if (stat(dir, &s) != 0 || !S_ISDIR(s.st_mode))
    {
        PLOG_ERROR("%s is not a valid directory.", dir);
        m_exists =  false;
    }
    else
    {
        m_exists = true;
    
        // Fetch the item names in that directory.
        DIR* dirObject;
        dirent* dirEntry;

        m_items = P_NULL;
        m_numberOfItems = 0;

        puint32 capacity = 32;
        puint8* itemData = PNEWARRAY(puint8, capacity * sizeof(PDirItem));
        pmemset(itemData, 0, sizeof(capacity * sizeof(PDirItem)));

        if ((dirObject = opendir(dir)) == NULL)
        {
            PLOG_ERROR("Failed to read directory %s.", dir);
            PDELETEARRAY(itemData);
        }
        else
        {
            char path[4096];
            while ((dirEntry = readdir(dirObject)) != NULL)
            {
                // Find first file will always return "." and ".." 
                // as the first two directories.
                if (pstrcmp(dirEntry->d_name, ".") != 0 && 
                    pstrcmp(dirEntry->d_name, "..") != 0)
                {
                    //Build up our file path using the passed in
                    //  [sDir] and the file/foldername we just found:
                    psprintf(path, 4096, "%s\\%s", dir, dirEntry->d_name);

                    //Is the entity a File or Folder?
                    if (dirEntry->d_type == DT_DIR)
                    {
                        // TODO: use the absolute path.
                        new (itemData + m_numberOfItems * sizeof(PDirItem)) PDirItem(P_DIR_ITEM_DIRECTORY, path);
                        m_numberOfItems++;
                    }
                    else if (dirEntry->d_type == DT_REG)
                    {
                        // TODO: use the absolute path.
                        new (itemData + m_numberOfItems * sizeof(PDirItem)) PDirItem(P_DIR_ITEM_FILE, path);
                        m_numberOfItems++;
                    }
                    else
                    {
                        PLOG_WARNING("%s is not supported.", path);
                    }

                    if (m_numberOfItems > capacity)
                    {
                        resizeItemArray(itemData, capacity, 2 * capacity);
                        capacity *= 2;
                    }
                }
            }

            closedir(dirObject); //Always, Always, clean things up!
        
            m_items = reinterpret_cast<PDirItem*>(itemData);
        }
    }
}
Exemple #13
0
PImage::PImage(const pchar *path, PInputStream &inputStream)
{
    m_data = P_NULL;
    m_width = 0;
    m_height = 0;
    m_pixelFormat = P_IMAGE_PIXELFORMAT_UNKNOWN;

    // Find the type of image by checking the prefix of the path.
    const pchar* suffix = pstrrchr(path, '.');
    if (suffix == P_NULL)
    {
        PLOG_ERROR("Fail to recognize image format");
    } 
    else
    {
        suffix += 1;

#if P_ENABLE_IMAGE_PNG == 1
        if (pstrcmp(suffix, "png") == 0)
        {
            if (!pImagePNGRead(inputStream, m_width, m_height, m_pixelFormat, m_data))
            {
                PLOG_ERROR("Failed to read PNG image %s", path);

                m_width = 0;
                m_height = 0;
                m_pixelFormat = P_IMAGE_PIXELFORMAT_UNKNOWN;
                m_data = P_NULL;
            }
        }
#endif // P_ENABLE_IMAGE_PNG == 1

#if P_ENABLE_IMAGE_TGA == 1
        if (pstrcmp(suffix, "tga") == 0)
        {
            if (!pImageTGARead(inputStream, m_width, m_height, m_pixelFormat, m_data))
            {
                PLOG_ERROR("Failed to read TGA image %s", path);

                m_width = 0;
                m_height = 0;
                m_pixelFormat = P_IMAGE_PIXELFORMAT_UNKNOWN;
                m_data = P_NULL;
            }
        }
#endif // P_ENABLE_IMAGE_TGA == 1

        // TODO: other image formats

        if (m_data != P_NULL)
        {
            PLOG_DEBUG("Load image %s succeeded", path);
        }
        else
        {
            PLOG_DEBUG("Unsupported image format");
            PLOG_DEBUG("Only supports");
#if P_ENABLE_IMAGE_PNG == 1
            PLOG_DEBUG("png");
#endif
#if P_ENABLE_IMAGE_TGA == 1
            PLOG_DEBUG("tga");
#endif
        }
    }
}
Exemple #14
0
pbool PScene::unpack(const PXmlElement* xmlElement)
{
    // Sanity check
    if (pstrcmp(xmlElement->name(), "scene") != 0)
    {
        PLOG_ERROR("It is not a scene element");
        return false;
    }

    // Delete all scene nodes
    PDELETE(m_root);

    PResourceManager *resourceManager = context()->module<PResourceManager>("resource-manager");

    // Delete all effects
    PList<PAbstractEffect *>::iterator it = m_effects.begin();
    PList<PAbstractEffect *>::iterator ie = m_effects.end();
    while (it != ie)
    {
        PAbstractEffect *effect = *it;
        effect->m_scene = P_NULL;
        PDELETE(effect);
        ++it;
    }

    // Recursively unpack its children
    PXmlElement childElement = xmlElement->firstChild();
    while (childElement.isValid())
    {
        if (pstrcmp(childElement.name(), "root") == 0)
        {
            const pchar *rootNameValue = childElement.attribute("name");
            PASSERT(rootNameValue != P_NULL);
            m_root = PNEW(PRootNode(rootNameValue, this));
            if (!m_root->unpack(&childElement))
            {
                return false;
            }
        }
        else if (pstrcmp(childElement.name(), "effect") == 0)
        {
            PAbstractEffect *effect = s_effectFactory.unpack(&childElement, this);
            if (effect == P_NULL)
            {
                return false;
            }
        }
        else if (pstrcmp(childElement.name(), "texture") == 0)
        {
            const pchar *textureId = childElement.attribute("id");
            if (textureId != P_NULL)
            {
                PTexture *texture = resourceManager->getTexture(textureId);
                if (texture == P_NULL)
                {
                    PLOG_ERROR("Failed to find texture %s.", textureId);
                }
                else
                {
                    const pchar *wrapValue = childElement.attribute("wrap");
                    if (wrapValue != P_NULL)
                    {
                        if (pstrcmp(wrapValue, "repeat") == 0)
                        {
                            texture->setRepeatWrappingEnabled(true, true);
                        }
                    }
                    
                    const pchar *mipmapValue = childElement.attribute("mipmap");
                    if (mipmapValue != P_NULL)
                    {
                        if (pstrcmp(mipmapValue, "true") == 0)
                        {
                            // TODO:
                            PASSERT_NOTIMPLEMENTED();
                        }
                    }
                }
            }
            else
            {
                PLOG_ERROR("Failed to find the id of the texture is missing.");
            }
        }
        else
        {
            PLOG_WARNING("Unknown element node (%s) in scene.", childElement.name());
        }

        childElement = childElement.nextSibling();
    } 

    // Find the main camera.
    const pchar *mainCameraValue = xmlElement->attribute("maincamera");
    m_mainCamera = P_NULL;
    if (mainCameraValue == P_NULL)
    {
        // When the main camera is not specified, use the first camera in the 
        // scene nodes as the main camera.
        PNode::iterator ni(m_root);
        
        PNode *node = *(++ni); // Skip the root
        while (node != P_NULL)
        {
            PCamera *camera = dynamic_cast<PCamera *>(node);
            if (camera != P_NULL)
            {
                m_mainCamera = camera;
                break;
            }
            node = *(++ni);
        }

        if (m_mainCamera == P_NULL)
        {
            PLOG_WARNING("No camera is found. The scene may not be rendered properly.");
        }
    }
    else
    {
        PNode::iterator ni(m_root);
        
        PNode *node = *(++ni); // Skip the root
        while (node != P_NULL)
        {
            if (node->name() == mainCameraValue)
            {
                PCamera *camera = dynamic_cast<PCamera *>(node);
                if (camera != P_NULL)
                {
                    m_mainCamera = camera;
                    break;
                }
            }
            node = *(++ni);
        }
        
        if (m_mainCamera == P_NULL)
        {
            PLOG_WARNING("There is no such camera called %s in the scene.");
        }
    }

    return true;
}
Exemple #15
0
pbool BContent::unpack(const PXmlElement *xmlElement)
{
    // Sanity check.
    if (pstrcmp(xmlElement->name(), "content") != 0)
    {
        PLOG_ERROR("It is not a content element");
        return false;
    }

    PXmlElement childElement = xmlElement->firstChild();
    while (childElement.isValid())
    {
        if (pstrcmp(childElement.name(), "entry") == 0)
        {
            const pchar *levelValue      = childElement.attribute("level");
            const pchar *textValue       = childElement.attribute("text");
            const pchar *pageNumberValue = childElement.attribute("pageno");

            if (levelValue == P_NULL ||
                textValue == P_NULL ||
                pageNumberValue == P_NULL)
            {
                PLOG_WARNING("entry is incomplete.");
            }
            else
            {
                pint32 pageNumber;
                pint32 level;
                if (pStringUnpackInt(levelValue, &level) == P_NULL ||
                    pStringUnpackInt(pageNumberValue, &pageNumber) == P_NULL)
                {
                    PLOG_WARNING("entry information is incomplete.");
                }
                else
                {
                    if ((puint32)pageNumber > m_book->numberOfPages())
                    {
                        PLOG_ERROR("entry's page number is not valide");
                    }
                    else
                    {
                        BContentEntry *entry = PNEW(BContentEntry);
                        entry->level      = level;
                        entry->text       = pstrdup(textValue);
                        entry->pageNumber = pageNumber;
                        m_entries.append(entry);
                    }
                }
            }
        }
        else
        {
            PLOG_WARNING("Unknown element node (%s) in entry.", childElement.name());
        }

        childElement = childElement.nextSibling();
    }


    return true;
}
pbool PBackground::unpack(const PXmlElement* xmlElement)
{
    PASSERT(xmlElement->isValid());

    const pchar *textureName = xmlElement->attribute("texture");
    if (textureName != P_NULL)
    {
        PResourceManager *resourceManager = scene()->context()->module<PResourceManager>("resource-manager");

        m_texture = resourceManager->getTexture(textureName);
        if (m_texture != P_NULL)
        {
            m_texture->retain();
        }
        material()->parameter("texture") = m_texture;
    }
    else
    {
        PLOG_ERROR("Failed to find the texture for PBackground in this xml node.");
        return false;
    }

    const pchar *p = P_NULL;

    const pchar *textureInfoValue = xmlElement->attribute("texinfo");
    if (textureInfoValue != P_NULL)
    {
        pfloat32 sx, sy;
        pfloat32 x, y;

        if ((p = pStringUnpackFloat(p, &sx)) != P_NULL &&
            (p = pStringUnpackFloat(p, &sy)) != P_NULL &&
            (p = pStringUnpackFloat(p, &x)) != P_NULL &&
            (p = pStringUnpackFloat(p, &y)) != P_NULL)
        {
	        m_textureInfo[0] = sx;
            m_textureInfo[1] = sy;
	        m_textureInfo[2] = x;
            m_textureInfo[3] = y;
        }
    }

    const pchar *sizeValue = xmlElement->attribute("size");
    if (sizeValue != P_NULL)
    {
        pfloat32 sx, sy;

        if ((p = pStringUnpackFloat(p, &sx)) != P_NULL &&
            (p = pStringUnpackFloat(p, &sy)) != P_NULL)
        {
	        m_sizeInfo[0] = sx;
            m_sizeInfo[1] = sy;
        }
    }

    const pchar *layoutValue = xmlElement->attribute("layout");
    pchar vLayout[16];
    pchar hLayout[16];
    if ((p = pStringUnpackString(layoutValue, hLayout)) != P_NULL && 
        (p = pStringUnpackString(layoutValue, vLayout)) != P_NULL)
    {
        puint32 layout = 0;

        if (pstrcmp(vLayout, "top") == 0)
        {
            layout |= LAYOUT_TOP;
        }
        else if (pstrcmp(vLayout, "middle") == 0)
        {
            layout |= LAYOUT_MIDDLE;
        }
        else if (pstrcmp(vLayout, "bottom") == 0)
        {
            layout |= LAYOUT_BOTTOM;
        }
        else if (pstrcmp(vLayout, "left") == 0)
        {
            layout |= LAYOUT_LEFT;
        }
        else if (pstrcmp(vLayout, "center") == 0)
        {
            layout |= LAYOUT_CENTER;
        }
        else if (pstrcmp(vLayout, "right") == 0)
        {
            layout |= LAYOUT_RIGHT;
        }
    
        setLayout(layout);
    }

    m_dirty = true;

    return true;
}
Exemple #17
0
OSErr
InflateFiles(void *hZip, void *hFind, short tgtVRefNum, long tgtDirID)
{
	OSErr		err = noErr;
	Boolean		bFoundAll = false;
	PRInt32		rv = 0;
	char		filename[255] = "\0", *lastslash, *leaf, macfilename[255] = "\0";
	Handle		fullPathH = 0;
	short 		fullPathLen = 0;
	Ptr			fullPathStr = 0;
	StringPtr	extractedFile = 0;
	FSSpec		extractedFSp, outFSp;
	
	
	while (!bFoundAll)
	{
		/* find next item if one exists */
		rv = ZIP_FindNext( hFind, filename, 255 );
		if (rv==ZIP_ERR_FNF)
		{
			bFoundAll = true;
			break;
		}
		else if (rv!=ZIP_OK)
			return rv;	
		
		/* ignore if item is a dir entry */	
		lastslash = strrchr(filename, '/');
		if (lastslash == (&filename[0] + strlen(filename) - 1)) /* dir entry encountered */
			continue;

		/* grab leaf filename only */
		if (lastslash == 0)
			leaf = filename;
		else
			leaf = lastslash + 1;
		
		/* obtain and NULL terminate the full path string */
		err = GetFullPath(tgtVRefNum, tgtDirID, "\p", &fullPathLen, &fullPathH); /* get dirpath */
		if (err!=noErr)
			return err;

        strcpy(macfilename, filename);        
        SLASHES_2_COLONS(macfilename);
		HLock(fullPathH);
		fullPathStr = NewPtrClear(fullPathLen + strlen(macfilename) + 1);
		strncat(fullPathStr, *fullPathH, fullPathLen);
		strcat(fullPathStr, macfilename);	/* tack on filename to dirpath */
		*(fullPathStr+fullPathLen+strlen(macfilename)) = '\0';
		
		/* create directories if file is nested in new subdirs */
		WhackDirectories(fullPathStr);
		err = DirCreateRecursive(fullPathStr);			
		
		if (err!=noErr)
		{
			if (fullPathStr) 
				DisposePtr((Ptr)fullPathStr);
			if (fullPathH)
			{
				HUnlock(fullPathH);				
				DisposeHandle(fullPathH);
			}
			continue; /* XXX do we want to do this? */
		}
		
		/* extract the file to its full path destination */
		rv = ZIP_ExtractFile( hZip, filename, fullPathStr );
		
		HUnlock(fullPathH);
		if (fullPathH)
			DisposeHandle(fullPathH);
		if (rv!=ZIP_OK)
		{
			if (fullPathStr)
				DisposePtr((Ptr)fullPathStr);			
			return rv;
		}
		
		/* AppleSingle decode if need be */
		extractedFile = CToPascal(fullPathStr); 
		if (extractedFile)
		{
			err = FSMakeFSSpec(0, 0, extractedFile, &extractedFSp);
			err = FSMakeFSSpec(0, 0, extractedFile, &outFSp);
			err = AppleSingleDecode(&extractedFSp, &outFSp);
			
			/* delete original file if named different than final file */
			if (!pstrcmp(extractedFSp.name, outFSp.name))
			{
				err = FSpDelete(&extractedFSp);
			}
		}
			
		/* record for cleanup later */
		FSMakeFSSpec(outFSp.vRefNum, outFSp.parID, outFSp.name, &coreFileList[currCoreFile]);
		currCoreFile++;
		
		/* progress bar update (roll the barber poll) */
		if (gWPtr)
			IdleControls(gWPtr);	
			
		if (extractedFile)
			DisposePtr((Ptr)extractedFile);
		if (fullPathStr)
			DisposePtr(fullPathStr);
	}
        
	return err;
}