コード例 #1
0
ファイル: fileio_legacy.c プロジェクト: gymdis/zstd
unsigned long long FIOv07_decompressFrame(dRessv07_t ress,
                                          FILE* foutput, FILE* finput)
{
    U64    frameSize = 0;
    size_t readSize  = 4;

    MEM_writeLE32(ress.srcBuffer, ZSTDv07_MAGICNUMBER);
    ZBUFFv07_decompressInitDictionary(ress.dctx, ress.dictBuffer, ress.dictBufferSize);

    while (1) {
        /* Decode */
        size_t inSize=readSize, decodedSize=ress.dstBufferSize;
        size_t toRead = ZBUFFv07_decompressContinue(ress.dctx, ress.dstBuffer, &decodedSize, ress.srcBuffer, &inSize);
        if (ZBUFFv07_isError(toRead)) EXM_THROW(36, "Decoding error : %s", ZBUFFv07_getErrorName(toRead));
        readSize -= inSize;

        /* Write block */
        { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, decodedSize, foutput);
          if (sizeCheck != decodedSize) EXM_THROW(37, "Write error : unable to write data block to destination file"); }
        frameSize += decodedSize;
        DISPLAYUPDATE(2, "\rDecoded : %u MB...     ", (U32)(frameSize>>20) );

        if (toRead == 0) break;
        if (readSize) EXM_THROW(38, "Decoding error : should consume entire input");

        /* Fill input buffer */
        if (toRead > ress.srcBufferSize) EXM_THROW(34, "too large block");
        readSize = fread(ress.srcBuffer, 1, toRead, finput);
        if (readSize != toRead) EXM_THROW(35, "Read error");
    }

    return frameSize;
}
コード例 #2
0
ファイル: fileio_legacy.c プロジェクト: gymdis/zstd
unsigned long long FIOv01_decompressFrame(FILE* foutput, FILE* finput)
{
    size_t const outBuffSize = 512 KB;
    BYTE* outBuff = (BYTE*)malloc(outBuffSize);
    size_t inBuffSize = 128 KB + 8;
    BYTE inBuff[128 KB + 8];
    BYTE* op = outBuff;
    BYTE* const oend = outBuff + outBuffSize;
    U64   filesize = 0;
    size_t toRead;
    size_t sizeCheck;
    ZSTDv01_Dctx* dctx = ZSTDv01_createDCtx();


    /* init */
    if (outBuff==NULL) EXM_THROW(41, "Error : not enough memory to decode legacy frame");

    /* restore header, already read from input */
    MEM_writeLE32(inBuff, ZSTDv01_magicNumberLE);
    sizeCheck = ZSTDv01_decompressContinue(dctx, NULL, 0, inBuff, sizeof(ZSTDv01_magicNumberLE));   /* Decode frame header */
    if (ZSTDv01_isError(sizeCheck)) EXM_THROW(42, "Error decoding legacy header");

    /* Main decompression Loop */
    toRead = ZSTDv01_nextSrcSizeToDecompress(dctx);
    while (toRead){
        size_t readSize, decodedSize;

        /* Fill input buffer */
        if (toRead > inBuffSize)
            EXM_THROW(43, "too large block");
        readSize = fread(inBuff, 1, toRead, finput);
        if (readSize != toRead)
            EXM_THROW(44, "Read error");

        /* Decode block */
        decodedSize = ZSTDv01_decompressContinue(dctx, op, oend-op, inBuff, readSize);
        if (ZSTDv01_isError(decodedSize)) EXM_THROW(45, "Decoding error : input corrupted");

        if (decodedSize) {  /* not a header */
            /* Write block */
            sizeCheck = fwrite(op, 1, decodedSize, foutput);
            if (sizeCheck != decodedSize) EXM_THROW(46, "Write error : unable to write data block to destination file");
            filesize += decodedSize;
            op += decodedSize;
            if (op==oend) op = outBuff;
            DISPLAYUPDATE(2, "\rDecoded : %u MB...     ", (U32)(filesize>>20) );
        }

        /* prepare for next Block */
        toRead = ZSTDv01_nextSrcSizeToDecompress(dctx);
    }

    /* release resources */
    free(outBuff);
    free(dctx);
    return filesize;
}
コード例 #3
0
/* ZSTDMT_flushNextJob() :
 * output : will be updated with amount of data flushed .
 * blockToFlush : if >0, the function will block and wait if there is no data available to flush .
 * @return : amount of data remaining within internal buffer, 1 if unknown but > 0, 0 if no more, or an error code */
static size_t ZSTDMT_flushNextJob(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsigned blockToFlush)
{
    unsigned const wJobID = zcs->doneJobID & zcs->jobIDMask;
    if (zcs->doneJobID == zcs->nextJobID) return 0;   /* all flushed ! */
    PTHREAD_MUTEX_LOCK(&zcs->jobCompleted_mutex);
    while (zcs->jobs[wJobID].jobCompleted==0) {
        DEBUGLOG(5, "waiting for jobCompleted signal from job %u", zcs->doneJobID);
        if (!blockToFlush) { pthread_mutex_unlock(&zcs->jobCompleted_mutex); return 0; }  /* nothing ready to be flushed => skip */
        pthread_cond_wait(&zcs->jobCompleted_cond, &zcs->jobCompleted_mutex);  /* block when nothing available to flush */
    }
    pthread_mutex_unlock(&zcs->jobCompleted_mutex);
    /* compression job completed : output can be flushed */
    {   ZSTDMT_jobDescription job = zcs->jobs[wJobID];
        if (!job.jobScanned) {
            if (ZSTD_isError(job.cSize)) {
                DEBUGLOG(5, "compression error detected ");
                ZSTDMT_waitForAllJobsCompleted(zcs);
                ZSTDMT_releaseAllJobResources(zcs);
                return job.cSize;
            }
            ZSTDMT_releaseCCtx(zcs->cctxPool, job.cctx);
            zcs->jobs[wJobID].cctx = NULL;
            DEBUGLOG(5, "zcs->params.fParams.checksumFlag : %u ", zcs->params.fParams.checksumFlag);
            if (zcs->params.fParams.checksumFlag) {
                XXH64_update(&zcs->xxhState, (const char*)job.srcStart + job.dictSize, job.srcSize);
                if (zcs->frameEnded && (zcs->doneJobID+1 == zcs->nextJobID)) {  /* write checksum at end of last section */
                    U32 const checksum = (U32)XXH64_digest(&zcs->xxhState);
                    DEBUGLOG(4, "writing checksum : %08X \n", checksum);
                    MEM_writeLE32((char*)job.dstBuff.start + job.cSize, checksum);
                    job.cSize += 4;
                    zcs->jobs[wJobID].cSize += 4;
            }   }
            ZSTDMT_releaseBuffer(zcs->buffPool, job.src);
            zcs->jobs[wJobID].srcStart = NULL;
            zcs->jobs[wJobID].src = g_nullBuffer;
            zcs->jobs[wJobID].jobScanned = 1;
        }
        {   size_t const toWrite = MIN(job.cSize - job.dstFlushed, output->size - output->pos);
            DEBUGLOG(4, "Flushing %u bytes from job %u ", (U32)toWrite, zcs->doneJobID);
            memcpy((char*)output->dst + output->pos, (const char*)job.dstBuff.start + job.dstFlushed, toWrite);
            output->pos += toWrite;
            job.dstFlushed += toWrite;
        }
        if (job.dstFlushed == job.cSize) {   /* output buffer fully flushed => move to next one */
            ZSTDMT_releaseBuffer(zcs->buffPool, job.dstBuff);
            zcs->jobs[wJobID].dstBuff = g_nullBuffer;
            zcs->jobs[wJobID].jobCompleted = 0;
            zcs->doneJobID++;
        } else {
            zcs->jobs[wJobID].dstFlushed = job.dstFlushed;
        }
        /* return value : how many bytes left in buffer ; fake it to 1 if unknown but >0 */
        if (job.cSize > job.dstFlushed) return (job.cSize - job.dstFlushed);
        if (zcs->doneJobID < zcs->nextJobID) return 1;   /* still some buffer to flush */
        zcs->allJobsCompleted = zcs->frameEnded;   /* frame completed and entirely flushed */
        return 0;   /* everything flushed */
}   }
コード例 #4
0
ファイル: zstdseek_compress.c プロジェクト: ajdavis/mongo
static inline size_t ZSTD_stwrite32(ZSTD_frameLog* fl,
                                    ZSTD_outBuffer* output, U32 const value,
                                    U32 const offset)
{
    if (fl->seekTablePos < offset + 4) {
        BYTE tmp[4]; /* so that we can work with buffers too small to write a whole word to */
        size_t const lenWrite =
                MIN(output->size - output->pos, offset + 4 - fl->seekTablePos);
        MEM_writeLE32(tmp, value);
        memcpy((BYTE*)output->dst + output->pos,
               tmp + (fl->seekTablePos - offset), lenWrite);
        output->pos += lenWrite;
        fl->seekTablePos += lenWrite;

        if (lenWrite < 4) return ZSTD_seekable_seekTableSize(fl) - fl->seekTablePos;
    }
    return 0;
}