Beispiel #1
0
static void *LZMA_openArchive(const char *name, int forWriting)
{
    PHYSFS_uint64 len;
    LZMAarchive *archive = NULL;
    ISzAlloc allocImp;
    ISzAlloc allocTempImp;

    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
    BAIL_IF_MACRO(!LZMA_isArchive(name,forWriting), ERR_UNSUPPORTED_ARCHIVE, 0);

    archive = (LZMAarchive *) allocator.Malloc(sizeof (LZMAarchive));
    BAIL_IF_MACRO(archive == NULL, ERR_OUT_OF_MEMORY, NULL);

    archive->firstEntry = NULL;
    archive->lastEntry = NULL;

    if ((archive->stream.File = __PHYSFS_platformOpenRead(name)) == NULL)
    {
        allocator.Free(archive);
        return NULL;
    } /* if */

    /* Prepare structs for 7z */
    archive->stream.InStream.Read = SzFileReadImp;
    archive->stream.InStream.Seek = SzFileSeekImp;

    allocImp.Alloc = SzAllocPhysicsFS;
    allocImp.Free = SzFreePhysicsFS;

    allocTempImp.Alloc = SzAllocPhysicsFS;
    allocTempImp.Free = SzFreePhysicsFS;

    InitCrcTable();
    SzArDbExInit(&archive->db);
    if (lzma_err(SzArchiveOpen(&archive->stream.InStream, &archive->db,
                               &allocImp, &allocTempImp)) != SZ_OK)
    {
        __PHYSFS_platformClose(archive->stream.File);
        allocator.Free(archive);
        return NULL;
    } /* if */

    len = archive->db.Database.NumFolders * sizeof (LZMAfolder);
    archive->folder = (LZMAfolder *) allocator.Malloc(len);
    BAIL_IF_MACRO(archive->folder == NULL, ERR_OUT_OF_MEMORY, NULL);

    /*
     * Init with 0 so we know when a folder is already cached
     * Values will be set by LZMA_read()
     */
    memset(archive->folder, 0, (size_t) len);

    return(archive);
} /* LZMA_openArchive */
Beispiel #2
0
static PHYSFS_sint64 LZMA_read(PHYSFS_Io *io, void *outBuf, PHYSFS_uint64 len)
{
    LZMAfile *file = (LZMAfile *) io->opaque;

    size_t wantedSize = (size_t) len;
    const size_t remainingSize = file->item->Size - file->position;
    size_t fileSize = 0;

    BAIL_IF_MACRO(wantedSize == 0, ERRPASS, 0); /* quick rejection. */
    BAIL_IF_MACRO(remainingSize == 0, PHYSFS_ERR_PAST_EOF, 0);

    if (wantedSize > remainingSize)
        wantedSize = remainingSize;

    /* Only decompress the folder if it is not already cached */
    if (file->folder->cache == NULL)
    {
        const int rc = lzma_err(SzExtract(
            &file->archive->stream.inStream, /* compressed data */
            &file->archive->db, /* 7z's database, containing everything */
            file->index, /* Index into database arrays */
            /* Index of cached folder, will be changed by SzExtract */
            &file->folder->index,
            /* Cache for decompressed folder, allocated/freed by SzExtract */
            &file->folder->cache,
            /* Size of cache, will be changed by SzExtract */
            &file->folder->size,
            /* Offset of this file inside the cache, set by SzExtract */
            &file->offset,
            &fileSize, /* Size of this file */
            &file->archive->stream.allocImp,
            &file->archive->stream.allocTempImp));

        if (rc != SZ_OK)
            return -1;
    } /* if */

    /* Copy wanted bytes over from cache to outBuf */
    memcpy(outBuf, (file->folder->cache + file->offset + file->position),
            wantedSize);
    file->position += wantedSize; /* Increase virtual position */

    return wantedSize;
} /* LZMA_read */
Beispiel #3
0
static void *LZMA_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
{
    PHYSFS_uint8 sig[k7zSignatureSize];
    size_t len = 0;
    LZMAarchive *archive = NULL;

    assert(io != NULL);  /* shouldn't ever happen. */

    BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);

    if (io->read(io, sig, k7zSignatureSize) != k7zSignatureSize)
        return 0;
    BAIL_IF_MACRO(!TestSignatureCandidate(sig), PHYSFS_ERR_UNSUPPORTED, NULL);
    BAIL_IF_MACRO(!io->seek(io, 0), ERRPASS, NULL);

    archive = (LZMAarchive *) allocator.Malloc(sizeof (LZMAarchive));
    BAIL_IF_MACRO(archive == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);

    lzma_archive_init(archive);
    archive->stream.io = io;

    CrcGenerateTable();
    SzArDbExInit(&archive->db);
    if (lzma_err(SzArchiveOpen(&archive->stream.inStream,
                               &archive->db,
                               &archive->stream.allocImp,
                               &archive->stream.allocTempImp)) != SZ_OK)
    {
        SzArDbExFree(&archive->db, SzFreePhysicsFS);
        lzma_archive_exit(archive);
        return NULL; /* Error is set by lzma_err! */
    } /* if */

    len = archive->db.Database.NumFiles * sizeof (LZMAfile);
    archive->files = (LZMAfile *) allocator.Malloc(len);
    if (archive->files == NULL)
    {
        SzArDbExFree(&archive->db, SzFreePhysicsFS);
        lzma_archive_exit(archive);
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
    }

    /*
     * Init with 0 so we know when a folder is already cached
     * Values will be set by LZMA_openRead()
     */
    memset(archive->files, 0, len);

    len = archive->db.Database.NumFolders * sizeof (LZMAfolder);
    archive->folders = (LZMAfolder *) allocator.Malloc(len);
    if (archive->folders == NULL)
    {
        SzArDbExFree(&archive->db, SzFreePhysicsFS);
        lzma_archive_exit(archive);
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
    }

    /*
     * Init with 0 so we know when a folder is already cached
     * Values will be set by LZMA_read()
     */
    memset(archive->folders, 0, len);

    if(!lzma_files_init(archive))
    {
        SzArDbExFree(&archive->db, SzFreePhysicsFS);
        lzma_archive_exit(archive);
        BAIL_MACRO(PHYSFS_ERR_OTHER_ERROR, NULL);
    }

    return archive;
} /* LZMA_openArchive */
Beispiel #4
0
static PHYSFS_sint64 LZMA_read(fvoid *opaque, void *outBuffer,
                               PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
{
    LZMAentry *entry = (LZMAentry *) opaque;

    PHYSFS_sint64 wantedSize = objSize*objCount;
    PHYSFS_sint64 remainingSize = entry->file->Size - entry->position;

    size_t fileSize;
    ISzAlloc allocImp;
    ISzAlloc allocTempImp;

    BAIL_IF_MACRO(wantedSize == 0, NULL, 0); /* quick rejection. */
    BAIL_IF_MACRO(remainingSize == 0, ERR_PAST_EOF, 0);

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

    /* Prepare callbacks for 7z */
    allocImp.Alloc = SzAllocPhysicsFS;
    allocImp.Free = SzFreePhysicsFS;

    allocTempImp.Alloc = SzAllocPhysicsFS;
    allocTempImp.Free = SzFreePhysicsFS;

    /* Only decompress the folder if it is not allready cached */
    if (entry->archive->folder[entry->folderIndex].cache == NULL)
    {
        size_t tmpsize = entry->archive->folder[entry->folderIndex].size;
        int rc = lzma_err(SzExtract(
            &entry->archive->stream.InStream, /* compressed data */
            &entry->archive->db,
            entry->fileIndex,
            /* Index of cached folder, will be changed by SzExtract */
            &entry->archive->folder[entry->folderIndex].index,
            /* Cache for decompressed folder, allocated/freed by SzExtract */
            &entry->archive->folder[entry->folderIndex].cache,
            /* Size of cache, will be changed by SzExtract */
            &tmpsize,
            /* Offset of this file inside the cache, set by SzExtract */
            &entry->offset,
            &fileSize, /* Size of this file */
            &allocImp,
            &allocTempImp));

        entry->archive->folder[entry->folderIndex].size = tmpsize;
        if (rc != SZ_OK)
            return -1;
    } /* if */

    /* Copy wanted bytes over from cache to outBuffer */
/* !!! FIXME: strncpy for non-string data? */
	strncpy(outBuffer,
            (void*) (entry->archive->folder[entry->folderIndex].cache +
                     entry->offset + entry->position),
            (size_t) wantedSize);
    entry->position += wantedSize;
    return objCount;
} /* LZMA_read */