static int mvl_open(const char *filename, int forWriting,
                    void **fh, PHYSFS_uint32 *count)
{
    PHYSFS_uint8 buf[4];

    *fh = NULL;
    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);

    *fh = __PHYSFS_platformOpenRead(filename);
    BAIL_IF_MACRO(*fh == NULL, NULL, 0);
    
    if (__PHYSFS_platformRead(*fh, buf, 4, 1) != 1)
        goto openMvl_failed;

    if (memcmp(buf, "DMVL", 4) != 0)
    {
        __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
        goto openMvl_failed;
    } /* if */

    if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
        goto openMvl_failed;

    *count = PHYSFS_swapULE32(*count);

    return 1;

openMvl_failed:
    if (*fh != NULL)
        __PHYSFS_platformClose(*fh);

    *count = -1;
    *fh = NULL;
    return 0;
} /* mvl_open */
예제 #2
0
파일: hog.c 프로젝트: UIKit0/paragui
static int hog_open(const char *filename, int forWriting,
                    void **fh, PHYSFS_uint32 *count)
{
    PHYSFS_uint8 buf[13];
    PHYSFS_uint32 size;
    PHYSFS_sint64 pos;

    *count = 0;

    *fh = NULL;
    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);

    *fh = __PHYSFS_platformOpenRead(filename);
    BAIL_IF_MACRO(*fh == NULL, NULL, 0);

    if (__PHYSFS_platformRead(*fh, buf, 3, 1) != 1)
        goto openHog_failed;

    if (memcmp(buf, "DHF", 3) != 0)
    {
        __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
        goto openHog_failed;
    } /* if */

    while( 1 )
    {
        if (__PHYSFS_platformRead(*fh, buf, 13, 1) != 1)
            break;             //eof here is ok

        if (__PHYSFS_platformRead(*fh, &size, 4, 1) != 1)
            goto openHog_failed;

        size = PHYSFS_swapULE32(size);

        (*count)++;

        // Skip over entry
        pos = __PHYSFS_platformTell(*fh);
        if (pos == -1)
            goto openHog_failed;
        if (!__PHYSFS_platformSeek(*fh, pos + size))
            goto openHog_failed;
    }

    // Rewind to start of entries
    if (!__PHYSFS_platformSeek(*fh, 3))
        goto openHog_failed;

    return(1);

openHog_failed:
    if (*fh != NULL)
        __PHYSFS_platformClose(*fh);

    *count = -1;
    *fh = NULL;
    return(0);
} /* hog_open */
static int wad_load_entries(const char *name, int forWriting, WADinfo *info)
{
    void *fh = NULL;
    PHYSFS_uint32 fileCount;
    PHYSFS_uint32 directoryOffset;
    WADentry *entry;
    char lastDirectory[9];

    lastDirectory[8] = 0; /* Make sure lastDirectory stays null-terminated. */

    BAIL_IF_MACRO(!wad_open(name, forWriting, &fh, &fileCount,&directoryOffset), NULL, 0);
    info->entryCount = fileCount;
    info->entries = (WADentry *) allocator.Malloc(sizeof(WADentry)*fileCount);
    if (info->entries == NULL)
    {
        __PHYSFS_platformClose(fh);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
    } /* if */

    __PHYSFS_platformSeek(fh,directoryOffset);

    for (entry = info->entries; fileCount > 0; fileCount--, entry++)
    {
        if (__PHYSFS_platformRead(fh, &entry->startPos, 4, 1) != 1)
        {
            __PHYSFS_platformClose(fh);
            return 0;
        } /* if */
        
        if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
        {
            __PHYSFS_platformClose(fh);
            return 0;
        } /* if */

        if (__PHYSFS_platformRead(fh, &entry->name, 8, 1) != 1)
        {
            __PHYSFS_platformClose(fh);
            return 0;
        } /* if */

        entry->name[8] = '\0'; /* name might not be null-terminated in file. */
        entry->size = PHYSFS_swapULE32(entry->size);
        entry->startPos = PHYSFS_swapULE32(entry->startPos);
    } /* for */

    __PHYSFS_platformClose(fh);

    __PHYSFS_sort(info->entries, info->entryCount,
                  wad_entry_cmp, wad_entry_swap);
    return 1;
} /* wad_load_entries */
예제 #4
0
파일: hog.c 프로젝트: UIKit0/paragui
static int hog_load_entries(const char *name, int forWriting, HOGinfo *info)
{
    void *fh = NULL;
    PHYSFS_uint32 fileCount;
    HOGentry *entry;

    BAIL_IF_MACRO(!hog_open(name, forWriting, &fh, &fileCount), NULL, 0);
    info->entryCount = fileCount;
    info->entries = (HOGentry *) malloc(sizeof (HOGentry) * fileCount);
    if (info->entries == NULL)
    {
        __PHYSFS_platformClose(fh);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
    } /* if */

    for (entry = info->entries; fileCount > 0; fileCount--, entry++)
    {
        if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1)
        {
            __PHYSFS_platformClose(fh);
            return(0);
        } /* if */

        if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
        {
            __PHYSFS_platformClose(fh);
            return(0);
        } /* if */

        entry->size = PHYSFS_swapULE32(entry->size);
        entry->startPos = __PHYSFS_platformTell(fh);
        if (entry->startPos == -1)
        {
            __PHYSFS_platformClose(fh);
            return(0);
        }

        // Skip over entry
        if (!__PHYSFS_platformSeek(fh, entry->startPos + entry->size))
        {
            __PHYSFS_platformClose(fh);
            return(0);
        }
    } /* for */

    __PHYSFS_platformClose(fh);

    __PHYSFS_sort(info->entries, info->entryCount,
                  hog_entry_cmp, hog_entry_swap);
    return(1);
} /* hog_load_entries */
예제 #5
0
파일: hha.c 프로젝트: C4-sic/codetastrophe
static int HHA_load_entries(const char *name, int forWriting, HHAinfo *info)
{
    void *fh = NULL;
    PHYSFS_uint32 fileNameSize;
    PHYSFS_uint32 fileCount;
    HHAentry *entry;
    PHYSFS_uint32 buf[6];

    BAIL_IF_MACRO(!hha_open(name, forWriting, &fh, &fileNameSize, &fileCount), NULL, 0);
    info->entryCount = fileCount;
    info->filenames = (char *) allocator.Malloc(fileNameSize);
    if (info->filenames == NULL)
    {
        __PHYSFS_platformClose(fh);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
    } /* if */
    info->entries = (HHAentry *) allocator.Malloc(sizeof(HHAentry)*fileCount);
    if (info->entries == NULL)
    {
        __PHYSFS_platformClose(fh);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
    } /* if */
    
    if (__PHYSFS_platformRead(fh, info->filenames, 1, fileNameSize) != fileNameSize)
    {
        __PHYSFS_platformClose(fh);
        return(0);
    } 

    for (entry = info->entries; fileCount > 0; fileCount--, entry++)
    {
        if (__PHYSFS_platformRead(fh, buf, sizeof(PHYSFS_uint32), 6) != 6)
        {
            __PHYSFS_platformClose(fh);
            return(0);
        } /* if */

        entry->dir = info->filenames + PHYSFS_swapULE32(buf[0]);
        entry->name = info->filenames + PHYSFS_swapULE32(buf[1]);
        entry->compress = PHYSFS_swapULE32(buf[2]);
        entry->offset = PHYSFS_swapULE32(buf[3]);
        entry->uncompressed_size = PHYSFS_swapULE32(buf[4]);
        entry->compressed_size = PHYSFS_swapULE32(buf[5]);
    } /* for */

    __PHYSFS_platformClose(fh);

    __PHYSFS_sort(info->entries, info->entryCount,
                  HHA_entry_cmp, HHA_entry_swap);
    return(1);
} /* HHA_load_entries */
예제 #6
0
파일: dir.c 프로젝트: leonlee/tome
static PHYSFS_sint64 DIR_read(fvoid *opaque, void *buffer,
                              PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
    PHYSFS_sint64 retval;
    retval = __PHYSFS_platformRead(opaque, buffer, objSize, objCount);
    return(retval);
} /* DIR_read */
예제 #7
0
파일: zip.c 프로젝트: Dahrkael/PhysFS-AES
/*
 * Read an unsigned 8-bit int and swap to native byte order.
 */
static int readui8(void *in, PHYSFS_uint8 *val)
{
    PHYSFS_uint8 v;
    BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
    *val = v;
    return(1);
} /* readui8*/
예제 #8
0
/*
 * Read an unsigned 16-bit int and swap to native byte order.
 */
static int readui16(void *in, PHYSFS_uint16 *val)
{
    PHYSFS_uint16 v;
    BAIL_IF_MACRO(__PHYSFS_platformRead(in, &v, sizeof (v), 1) != 1, NULL, 0);
    *val = PHYSFS_swapULE16(v);
    return(1);
} /* readui16 */
예제 #9
0
SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size,
                        size_t *processedSize)
{
    CFileInStream *s = (CFileInStream *)object;
    size_t processedSizeLoc = __PHYSFS_platformRead(s->File, buffer, 1, size);
    if (processedSize != 0)
        *processedSize = processedSizeLoc;
    return SZ_OK;
} /* SzFileReadImp */
예제 #10
0
static int mvl_load_entries(const char *name, int forWriting, MVLinfo *info)
{
    void *fh = NULL;
    PHYSFS_uint32 fileCount;
    PHYSFS_uint32 location = 8;  /* sizeof sig. */
    MVLentry *entry;

    BAIL_IF_MACRO(!mvl_open(name, forWriting, &fh, &fileCount), NULL, 0);
    info->entryCount = fileCount;
    info->entries = (MVLentry *) allocator.Malloc(sizeof(MVLentry)*fileCount);
    if (info->entries == NULL)
    {
        __PHYSFS_platformClose(fh);
        BAIL_MACRO(ERR_OUT_OF_MEMORY, 0);
    } /* if */

    location += (17 * fileCount);

    for (entry = info->entries; fileCount > 0; fileCount--, entry++)
    {
        if (__PHYSFS_platformRead(fh, &entry->name, 13, 1) != 1)
        {
            __PHYSFS_platformClose(fh);
            return 0;
        } /* if */

        if (__PHYSFS_platformRead(fh, &entry->size, 4, 1) != 1)
        {
            __PHYSFS_platformClose(fh);
            return 0;
        } /* if */

        entry->size = PHYSFS_swapULE32(entry->size);
        entry->startPos = location;
        location += entry->size;
    } /* for */

    __PHYSFS_platformClose(fh);

    __PHYSFS_sort(info->entries, info->entryCount,
                  mvl_entry_cmp, mvl_entry_swap);
    return 1;
} /* mvl_load_entries */
예제 #11
0
파일: hha.c 프로젝트: C4-sic/codetastrophe
static int hha_open(const char *filename, int forWriting,
                    void **fh, PHYSFS_uint32 *filenameSize, PHYSFS_uint32 *count)
{
    PHYSFS_uint32 magic[2];

    *fh = NULL;
    
    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);
    
    *fh = __PHYSFS_platformOpenRead(filename);
    BAIL_IF_MACRO(*fh == NULL, NULL, 0);
    
    if (__PHYSFS_platformRead(*fh, magic, sizeof(PHYSFS_uint32), 2) != 2)
        goto openHHA_failed;

    magic[0] = PHYSFS_swapULE32(magic[0]);
    magic[1] = PHYSFS_swapULE32(magic[1]);
    if (!(magic[0] == HHA_FILE_MAGIC && magic[1] == HHA_FILE_VERSION))
    {
        __PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
        goto openHHA_failed;
    } /* if */
    
    if (__PHYSFS_platformRead(*fh, filenameSize, sizeof (PHYSFS_uint32), 1) != 1)
        goto openHHA_failed;
    *filenameSize = PHYSFS_swapULE32(*filenameSize);
    if (__PHYSFS_platformRead(*fh, count, sizeof (PHYSFS_uint32), 1) != 1)
        goto openHHA_failed;
    *count = PHYSFS_swapULE32(*count);

    return(1);

openHHA_failed:
    if (*fh != NULL)
        __PHYSFS_platformClose(*fh);

    *filenameSize = -1;
    *count = -1;
    *fh = NULL;
    return(0);
} /* HHA_open */
예제 #12
0
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxReqSize,
                        size_t *processedSize)
{
    CFileInStream *s = (CFileInStream *)object;
    PHYSFS_sint64 processedSizeLoc;
    if (maxReqSize > kBufferSize)
        maxReqSize = kBufferSize;
    processedSizeLoc = __PHYSFS_platformRead(s->File, g_Buffer, 1, maxReqSize);
    *buffer = g_Buffer;
    if (processedSize != NULL)
        *processedSize = (size_t) processedSizeLoc;
    return SZ_OK;
} /* SzFileReadImp */
예제 #13
0
파일: hog.c 프로젝트: UIKit0/paragui
static PHYSFS_sint64 HOG_read(FileHandle *handle, void *buffer,
                              PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
    HOGfileinfo *finfo = (HOGfileinfo *) (handle->opaque);
    HOGentry *entry = finfo->entry;
    PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
    PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
    PHYSFS_sint64 rc;

    if (objsLeft < objCount)
        objCount = objsLeft;

    rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
    if (rc > 0)
        finfo->curPos += (PHYSFS_uint32) (rc * objSize);

    return(rc);
} /* HOG_read */
예제 #14
0
static PHYSFS_sint64 WAD_read(fvoid *opaque, void *buffer,
                              PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
    WADfileinfo *finfo = (WADfileinfo *) opaque;
    WADentry *entry = finfo->entry;
    PHYSFS_uint32 bytesLeft = entry->size - finfo->curPos;
    PHYSFS_uint32 objsLeft = (bytesLeft / objSize);
    PHYSFS_sint64 rc;

    if (objsLeft < objCount)
        objCount = objsLeft;

    rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
    if (rc > 0)
        finfo->curPos += (PHYSFS_uint32) (rc * objSize);

    return rc;
} /* WAD_read */
예제 #15
0
static int LZMA_isArchive(const char *filename, int forWriting)
{
    PHYSFS_uint8 sig[k7zSignatureSize];
    PHYSFS_uint8 res;
    void *in;

    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);

    in = __PHYSFS_platformOpenRead(filename);
    BAIL_IF_MACRO(in == NULL, NULL, 0);

    if (__PHYSFS_platformRead(in, sig, k7zSignatureSize, 1) != 1)
        BAIL_MACRO(NULL, 0);

    /* Test whether sig is the 7z signature */
    res = TestSignatureCandidate(sig);

    __PHYSFS_platformClose(in);

    return res;
} /* LZMA_isArchive */
예제 #16
0
파일: hha.c 프로젝트: C4-sic/codetastrophe
static PHYSFS_sint64 HHA_read(fvoid *opaque, void *buffer,
                              PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
    HHAfileinfo *finfo = (HHAfileinfo *) opaque;
    HHAentry *entry = finfo->entry;
    PHYSFS_sint64 retval = 0;
    PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount;
    PHYSFS_sint64 avail = entry->uncompressed_size -
                          finfo->uncompressed_position;

    BAIL_IF_MACRO(maxread == 0, NULL, 0);    /* quick rejection. */

    if (avail < maxread)
    {
        maxread = avail - (avail % objSize);
        objCount = (PHYSFS_uint32) (maxread / objSize);
        BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0);  /* quick rejection. */
        __PHYSFS_setError(ERR_PAST_EOF);   /* this is always true here. */
    } /* if */


    if (entry->compress == HHA_COMPRESS_NONE)
    {
        retval = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount);
    }
    else if (entry->compress == HHA_COMPRESS_ZLIB)
    {
        finfo->zlib_stream.next_out = buffer;
        finfo->zlib_stream.avail_out = objSize * objCount;

        while (retval < maxread)
        {
            PHYSFS_uint32 before = finfo->zlib_stream.total_out;
            int rc;

            if (finfo->zlib_stream.avail_in == 0)
            {
                PHYSFS_sint64 br;

                br = entry->compressed_size - finfo->compressed_position;
                if (br > 0)
                {
                    if (br > ZIP_READBUFSIZE)
                        br = ZIP_READBUFSIZE;

                    br = __PHYSFS_platformRead(finfo->handle,
                                               finfo->buffer,
                                               1, (PHYSFS_uint32) br);
                    if (br <= 0)
                        break;

                    finfo->compressed_position += (PHYSFS_uint32) br;
                    finfo->zlib_stream.next_in = finfo->buffer;
                    finfo->zlib_stream.avail_in = (PHYSFS_uint32) br;
                } /* if */
            } /* if */

            rc = zlib_err(inflate(&finfo->zlib_stream, Z_SYNC_FLUSH));
            retval += (finfo->zlib_stream.total_out - before);

            if (rc != Z_OK)
                break;
        } /* while */

        retval /= objSize;
    }
    if (retval > 0)
        finfo->uncompressed_position += (PHYSFS_uint32) (retval * objSize);

    return(retval);
} /* HHA_read */
예제 #17
0
static PHYSFS_sint64 zip_find_end_of_central_dir(void *in, PHYSFS_sint64 *len)
{
    PHYSFS_uint8 buf[256];
    PHYSFS_sint32 i = 0;
    PHYSFS_sint64 filelen;
    PHYSFS_sint64 filepos;
    PHYSFS_sint32 maxread;
    PHYSFS_sint32 totalread = 0;
    int found = 0;
    PHYSFS_uint32 extra = 0;

    filelen = __PHYSFS_platformFileLength(in);
    BAIL_IF_MACRO(filelen == -1, NULL, 0);  /* !!! FIXME: unlocalized string */
    BAIL_IF_MACRO(filelen > 0xFFFFFFFF, "ZIP bigger than 2 gigs?!", 0);

    /*
     * Jump to the end of the file and start reading backwards.
     *  The last thing in the file is the zipfile comment, which is variable
     *  length, and the field that specifies its size is before it in the
     *  file (argh!)...this means that we need to scan backwards until we
     *  hit the end-of-central-dir signature. We can then sanity check that
     *  the comment was as big as it should be to make sure we're in the
     *  right place. The comment length field is 16 bits, so we can stop
     *  searching for that signature after a little more than 64k at most,
     *  and call it a corrupted zipfile.
     */

    if (sizeof (buf) < filelen)
    {
        filepos = filelen - sizeof (buf);
        maxread = sizeof (buf);
    } /* if */
    else
    {
        filepos = 0;
        maxread = (PHYSFS_uint32) filelen;
    } /* else */

    while ((totalread < filelen) && (totalread < 65557))
    {
        BAIL_IF_MACRO(!__PHYSFS_platformSeek(in, filepos), NULL, -1);

        /* make sure we catch a signature between buffers. */
        if (totalread != 0)
        {
            if (__PHYSFS_platformRead(in, buf, maxread - 4, 1) != 1)
                return(-1);
            *((PHYSFS_uint32 *) (&buf[maxread - 4])) = extra;
            totalread += maxread - 4;
        } /* if */
        else
        {
            if (__PHYSFS_platformRead(in, buf, maxread, 1) != 1)
                return(-1);
            totalread += maxread;
        } /* else */

        extra = *((PHYSFS_uint32 *) (&buf[0]));

        for (i = maxread - 4; i > 0; i--)
        {
            if ((buf[i + 0] == 0x50) &&
                (buf[i + 1] == 0x4B) &&
                (buf[i + 2] == 0x05) &&
                (buf[i + 3] == 0x06) )
            {
                found = 1;  /* that's the signature! */
                break;  
            } /* if */
        } /* for */

        if (found)
            break;

        filepos -= (maxread - 4);
    } /* while */

    BAIL_IF_MACRO(!found, ERR_NOT_AN_ARCHIVE, -1);

    if (len != NULL)
        *len = filelen;

    return(filepos + i);
} /* zip_find_end_of_central_dir */
예제 #18
0
파일: zip.c 프로젝트: Dahrkael/PhysFS-AES
static PHYSFS_sint64 ZIP_read(fvoid *opaque, void *buf,
                              PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
	int total, i = 0;
	
    ZIPfileinfo *finfo = (ZIPfileinfo *) opaque;
    ZIPentry *entry = finfo->entry;
    PHYSFS_sint64 retval = 0;
    PHYSFS_sint64 maxread = ((PHYSFS_sint64) objSize) * objCount;
    PHYSFS_sint64 avail = entry->uncompressed_size -
                          finfo->uncompressed_position;

    BAIL_IF_MACRO(maxread == 0, NULL, 0);    /* quick rejection. */

    if (avail < maxread)
    {
        maxread = avail - (avail % objSize);
        objCount = (PHYSFS_uint32) (maxread / objSize);
        BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0);  /* quick rejection. */
        __PHYSFS_setError(ERR_PAST_EOF);   /* this is always true here. */
    } /* if */

    if (entry->compression_method == COMPMETH_NONE)
    {
		if (entry->encrypted == AES_ENCRYPTED)
		{
			retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount);
			total = maxread;
			while (total > 16)
			{
				fcrypt_decrypt(((char*)buf) + i, 16, &finfo->zctx);
				i += 16;
				total -= 16;
			}
			if (total > 0)
			{ fcrypt_decrypt(((char*)buf) + i, total, &finfo->zctx); }
		}
		else
		{
			retval = __PHYSFS_platformRead(finfo->handle, buf, objSize, objCount);
		}
    } /* if */
    else
    {
        finfo->stream.next_out = buf;
        finfo->stream.avail_out = objSize * objCount;

        while (retval < maxread)
        {
            PHYSFS_uint32 before = finfo->stream.total_out;
            int rc;

            if (finfo->stream.avail_in == 0)
            {
                PHYSFS_sint64 br;

                br = entry->compressed_size - finfo->compressed_position;
                if (br > 0)
                {
                    if (br > ZIP_READBUFSIZE)
                        br = ZIP_READBUFSIZE;

                    br = __PHYSFS_platformRead(finfo->handle,
                                               finfo->buffer,
                                               1, (PHYSFS_uint32) br);
					if (br <= 0) { break; }

					if (entry->encrypted == AES_ENCRYPTED)
					{
						total = br;
						i = 0;
						while (total > 16)
						{
							fcrypt_decrypt(finfo->buffer + i, 16, &finfo->zctx);
							i += 16;
							total -= 16;
						}
						if (total > 0)
						{ fcrypt_decrypt(finfo->buffer + i, total, &finfo->zctx); }
					}
                    finfo->compressed_position += (PHYSFS_uint32) br;
                    finfo->stream.next_in = finfo->buffer;
                    finfo->stream.avail_in = (PHYSFS_uint32) br;
                } /* if */
            } /* if */

            rc = zlib_err(inflate(&finfo->stream, Z_SYNC_FLUSH));
            retval += (finfo->stream.total_out - before);

            if (rc != Z_OK)
                break;
        } /* while */

        retval /= objSize;
    } /* else */

    if (retval > 0)
        finfo->uncompressed_position += (PHYSFS_uint32) (retval * objSize);

    return(retval);
} /* ZIP_read */