Ejemplo n.º 1
0
static PyObject *py_lz4f_getFrameInfo(PyObject *self, PyObject *args) {
    const char *source;
    int src_size;
    LZ4F_decompressionContext_t dCtx;
    LZ4F_frameInfo_t frameInfo;
    PyObject *blkSize;
    PyObject *blkMode;
    PyObject *contChkFlag;
    PyObject *py_dCtx;
    PyObject *result = PyDict_New();
    size_t ssrc_size;
    size_t err;

    (void)self;
    if (!PyArg_ParseTuple(args, "s#O", &source, &src_size, &py_dCtx)) {
        return NULL;
    }

    dCtx = (LZ4F_decompressionContext_t)PyCapsule_GetPointer(py_dCtx, NULL);
    ssrc_size = (size_t)src_size;

    err = LZ4F_getFrameInfo(dCtx, &frameInfo, (unsigned char*)source, &ssrc_size);
    CHECK(LZ4F_isError(err), "Failed getting frameInfo. (error %i)", (int)err);

    blkSize = PyInt_FromSize_t(frameInfo.blockSizeID);
    blkMode = PyInt_FromSize_t(frameInfo.blockMode);
    contChkFlag = PyInt_FromSize_t(frameInfo.contentChecksumFlag);
    PyDict_SetItemString(result, "blkSize", blkSize);
    PyDict_SetItemString(result, "blkMode", blkMode);
    PyDict_SetItemString(result, "chkFlag", contChkFlag);


    return result;
_output_error:
    return Py_None;
}
Ejemplo n.º 2
0
SEXP
do_lzDecompress (SEXP FROM)
{
  SEXP ANS;
  LZ4F_decompressionContext_t ctx;

  LZ4F_frameInfo_t info;
  char *from;
  char *ans;
  void *src;
  size_t m, n, output_size, input_size = xlength(FROM);
  size_t ibuf, obuf, icum, ocum;
  if(TYPEOF(FROM) != RAWSXP) error("'from' must be raw or character");
  from = (char *)RAW(FROM);

/* An implementation following the standard API would do this:
 *   LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION);
 *   if (LZ4F_isError (err)) error("could not create LZ4 decompression context");
 *   ...
 *   LZ4F_freeDecompressionContext(ctx);
 * The problem with that approach is that LZ4F_createDecompressionContext
 * allocates memory with calloc internally. Later, if R's allocVector fails,
 * for example, or if R interrupts this function somewhere in '...' then
 * those internal allocations in LZ4F_createDecompressionContext leak--that is
 * they aren't ever de-allocated.
 *
 * We explicitly allocat the LZ4F_decompressionContext_t pointer using a
 * replica of the internal LZ4F_dctx_t structure defined near the top of this
 * file, see the note and corresponding warning! We allocate on the heap (via
 * R_alloc) here instead of a seemingly simpler stack allocation because LZ4
 * indicates that the address needs to be aligned to 8-byte boundaries which is
 * provided by R_alloc, see:
 * https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Transient-storage-allocation
 */
  LZ4F_dctx_t *dctxPtr = (LZ4F_dctx_t *)R_alloc(1, sizeof(LZ4F_dctx_t));
  memset(dctxPtr, 0, sizeof(LZ4F_dctx_t));
  dctxPtr->version = LZ4F_VERSION;
  ctx = (LZ4F_decompressionContext_t)dctxPtr;
  m   = input_size;
  n   = LZ4F_getFrameInfo(ctx, &info, (void *)from, &input_size);
  if (LZ4F_isError (n)) error("LZ4F_getFrameInfo");
  src = from + input_size; // lz4 frame header offset
  output_size = (size_t) info.contentSize; 
  ANS = allocVector(RAWSXP, output_size);
  ans = (char *)RAW(ANS);

  input_size = m - input_size;
  icum = 0;
  ibuf = lzframe_chunksize;
  if(ibuf > input_size) ibuf = input_size;
  ocum = 0;
  obuf = output_size;

  for(;;)
  {
    n = LZ4F_decompress(ctx, ans, &obuf, src, &ibuf, NULL); 
    if (LZ4F_isError (n)) error("LZ4F_decompress");
    icum = icum + ibuf;
    ocum = ocum + obuf;
    if(icum >= input_size) break;
    ans = ans + obuf;
    src = src + ibuf;
    ibuf = lzframe_chunksize;
    if(ibuf > (input_size - icum)) ibuf = input_size - icum;
    obuf = output_size - ocum;
  }

  return ANS;
}
Ejemplo n.º 3
0
Archivo: sgtest.c Proyecto: infidob/lz4
static int verify_basic_LZ4F_decompression(const void* compressedBuffer, int cSize, U64 crcOrig, void* decodedBuffer, const size_t decodedBufferSize)
{
    DISPLAYLEVEL(3, "%s (cSize %i, crcOrig %08x, decodedBufferSize %i)\n", __FUNCTION__, cSize, (unsigned int)crcOrig, (int)decodedBufferSize);
    LZ4F_decompressionContext_t dCtx = NULL;
    U64 crcDest;
    size_t compressedBufferSize = cSize;
    BYTE* op = (BYTE*) decodedBuffer;
    BYTE* const oend = (BYTE*) decodedBuffer + decodedBufferSize;
    const BYTE* ip = (const BYTE*) compressedBuffer;
    const BYTE* const iend = (const BYTE*) compressedBuffer + cSize;
    LZ4F_errorCode_t errorCode = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
    UT_VERIFY(!LZ4F_isError(errorCode), return __LINE__);

    memset(decodedBuffer, 0, decodedBufferSize);

    DISPLAYLEVEL(3, "Single Block : \n");
    size_t destSize = decodedBufferSize;
    errorCode = LZ4F_decompress(dCtx, decodedBuffer, &destSize, compressedBuffer, &compressedBufferSize, NULL);
    UT_VERIFY(!LZ4F_isError(errorCode), return __LINE__);

    crcDest = XXH64(decodedBuffer, decodedBufferSize, 1);
    DISPLAYLEVEL(3, "Regenerated %i bytes (%08x)\n", (int )decodedBufferSize, (unsigned int)crcDest);
    UT_VERIFY(crcDest == crcOrig, return __LINE__);

    memset(decodedBuffer, 0, decodedBufferSize);

    DISPLAYLEVEL(4, "Reusing decompression context \n");
    {
        size_t iSize = compressedBufferSize - 4;
        const BYTE* cBuff = (const BYTE*) compressedBuffer;
        DISPLAYLEVEL(3, "Missing last 4 bytes : ");
        destSize = decodedBufferSize;
        errorCode = LZ4F_decompress(dCtx, decodedBuffer, &destSize, cBuff, &iSize, NULL);
        UT_VERIFY(!LZ4F_isError(errorCode), return __LINE__);
        UT_VERIFY(errorCode, return __LINE__);
        crcDest = XXH64(decodedBuffer, destSize, 1);
        DISPLAYLEVEL(3, "crcDest (%08x)\n", (unsigned int)crcDest);

        DISPLAYLEVEL(3, "indeed, request %u bytes \n", (unsigned )errorCode);
        cBuff += iSize;
        iSize = errorCode;
        errorCode = LZ4F_decompress(dCtx, decodedBuffer, &destSize, cBuff, &iSize, NULL);
        UT_VERIFY(errorCode == 0, return __LINE__);

        crcDest = XXH64(decodedBuffer, decodedBufferSize, 1);
        DISPLAYLEVEL(3, "crcDest (%08x)\n", (unsigned int)crcDest);
        UT_VERIFY(crcDest == crcOrig, return __LINE__);
    }
    {
        size_t oSize = 0;
        size_t iSize = 0;
        LZ4F_frameInfo_t fi;
        DISPLAYLEVEL(3, "Start by feeding 0 bytes, to get next input size : ");
        errorCode = LZ4F_decompress(dCtx, NULL, &oSize, ip, &iSize, NULL);
        UT_VERIFY(!LZ4F_isError(errorCode), return __LINE__);

        DISPLAYLEVEL(3, " %u  \n", (unsigned )errorCode);
        DISPLAYLEVEL(3, "get FrameInfo on null input : ");
        errorCode = LZ4F_getFrameInfo(dCtx, &fi, ip, &iSize);
        UT_VERIFY(errorCode == (size_t) -LZ4F_ERROR_frameHeader_incomplete, return __LINE__);

        DISPLAYLEVEL(3, " correctly failed : %s \n", LZ4F_getErrorName(errorCode));
        DISPLAYLEVEL(3, "get FrameInfo on not enough input : ");
        iSize = 6;
        errorCode = LZ4F_getFrameInfo(dCtx, &fi, ip, &iSize);
        UT_VERIFY(errorCode == (size_t) -LZ4F_ERROR_frameHeader_incomplete, return __LINE__);

        DISPLAYLEVEL(3, " correctly failed : %s \n", LZ4F_getErrorName(errorCode));
        ip += iSize;
        DISPLAYLEVEL(3, "get FrameInfo on enough input : ");
        iSize = 15 - iSize;
        errorCode = LZ4F_getFrameInfo(dCtx, &fi, ip, &iSize);
        UT_VERIFY(!LZ4F_isError(errorCode), return __LINE__);

        DISPLAYLEVEL(3, " correctly decoded \n");
        ip += iSize;
    }
    DISPLAYLEVEL(3, "Byte after byte : \n");
    while (ip < iend) {
        size_t oSize = oend - op;
        size_t iSize = 1;
        errorCode = LZ4F_decompress(dCtx, op, &oSize, ip, &iSize, NULL);
        UT_VERIFY(!LZ4F_isError(errorCode), return __LINE__);

        op += oSize;
        ip += iSize;
    }
    crcDest = XXH64(decodedBuffer, decodedBufferSize, 1);
    UT_VERIFY(crcDest == crcOrig, return __LINE__);

    DISPLAYLEVEL(3, "Regenerated %u/%u bytes \n", (unsigned )(op - (BYTE* )decodedBuffer), (unsigned )decodedBufferSize);
    errorCode = LZ4F_freeDecompressionContext(dCtx);
    UT_VERIFY(!LZ4F_isError(errorCode), return __LINE__);

    dCtx = NULL;
    return 0;
}