summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/lz4frame.c45
-rw-r--r--lib/lz4frame.h50
-rw-r--r--tests/frametest.c11
3 files changed, 64 insertions, 42 deletions
diff --git a/lib/lz4frame.c b/lib/lz4frame.c
index c65256d..258d85e 100644
--- a/lib/lz4frame.c
+++ b/lib/lz4frame.c
@@ -522,30 +522,31 @@ size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
*****************************************************/
struct LZ4F_CDict_s {
+ LZ4F_CustomMem cmem;
void* dictContent;
LZ4_stream_t* fastCtx;
LZ4_streamHC_t* HCCtx;
}; /* typedef'd to LZ4F_CDict within lz4frame_static.h */
-/*! LZ4F_createCDict() :
- * When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once.
- * LZ4F_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
- * LZ4F_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.
- * @dictBuffer can be released after LZ4F_CDict creation, since its content is copied within CDict
- * @return : digested dictionary for compression, or NULL if failed */
-LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize)
+LZ4F_CDict*
+LZ4F_createCDict_advanced(LZ4F_CustomMem cmem, const void* dictBuffer, size_t dictSize)
{
const char* dictStart = (const char*)dictBuffer;
- LZ4F_CDict* const cdict = (LZ4F_CDict*)LZ4F_malloc(sizeof(*cdict), LZ4F_defaultCMem);
- DEBUGLOG(4, "LZ4F_createCDict");
+ LZ4F_CDict* const cdict = (LZ4F_CDict*)LZ4F_malloc(sizeof(*cdict), cmem);
+ DEBUGLOG(4, "LZ4F_createCDict_advanced");
if (!cdict) return NULL;
+ cdict->cmem = cmem;
if (dictSize > 64 KB) {
dictStart += dictSize - 64 KB;
dictSize = 64 KB;
}
- cdict->dictContent = LZ4F_malloc(dictSize, LZ4F_defaultCMem);
- cdict->fastCtx = LZ4_createStream();
- cdict->HCCtx = LZ4_createStreamHC();
+ cdict->dictContent = LZ4F_malloc(dictSize, cmem);
+ cdict->fastCtx = (LZ4_stream_t*)LZ4F_malloc(sizeof(LZ4_stream_t), cmem);
+ if (cdict->fastCtx)
+ LZ4_initStream(cdict->fastCtx, sizeof(LZ4_stream_t));
+ cdict->HCCtx = (LZ4_streamHC_t*)LZ4F_malloc(sizeof(LZ4_streamHC_t), cmem);
+ if (cdict->HCCtx)
+ LZ4_initStream(cdict->HCCtx, sizeof(LZ4_streamHC_t));
if (!cdict->dictContent || !cdict->fastCtx || !cdict->HCCtx) {
LZ4F_freeCDict(cdict);
return NULL;
@@ -557,13 +558,25 @@ LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize)
return cdict;
}
+/*! LZ4F_createCDict() :
+ * When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once.
+ * LZ4F_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
+ * LZ4F_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.
+ * @dictBuffer can be released after LZ4F_CDict creation, since its content is copied within CDict
+ * @return : digested dictionary for compression, or NULL if failed */
+LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize)
+{
+ DEBUGLOG(4, "LZ4F_createCDict");
+ return LZ4F_createCDict_advanced(LZ4F_defaultCMem, dictBuffer, dictSize);
+}
+
void LZ4F_freeCDict(LZ4F_CDict* cdict)
{
if (cdict==NULL) return; /* support free on NULL */
- LZ4F_free(cdict->dictContent, LZ4F_defaultCMem);
- LZ4_freeStream(cdict->fastCtx);
- LZ4_freeStreamHC(cdict->HCCtx);
- LZ4F_free(cdict, LZ4F_defaultCMem);
+ LZ4F_free(cdict->dictContent, cdict->cmem);
+ LZ4F_free(cdict->fastCtx, cdict->cmem);
+ LZ4F_free(cdict->HCCtx, cdict->cmem);
+ LZ4F_free(cdict, cdict->cmem);
}
diff --git a/lib/lz4frame.h b/lib/lz4frame.h
index 0d2ebf9..74df963 100644
--- a/lib/lz4frame.h
+++ b/lib/lz4frame.h
@@ -551,30 +551,6 @@ typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM)
LZ4FLIB_STATIC_API LZ4F_errorCodes LZ4F_getErrorCode(size_t functionResult);
-/*! Custom memory allocation :
- * These prototypes make it possible to pass custom allocation/free functions.
- * LZ4F_customMem is provided at state creation time, using LZ4F_createCompressionContext_advanced() listed below.
- * All allocation/free operations will be completed using these custom variants instead of regular <stdlib.h> ones.
- */
-typedef void* (*LZ4F_AllocFunction) (void* opaqueState, size_t size);
-typedef void* (*LZ4F_CallocFunction) (void* opaqueState, size_t size);
-typedef void (*LZ4F_FreeFunction) (void* opaqueState, void* address);
-typedef struct {
- LZ4F_AllocFunction customAlloc;
- LZ4F_CallocFunction customCalloc; /* optional; when not defined, uses customAlloc + memset */
- LZ4F_FreeFunction customFree;
- void* opaqueState;
-} LZ4F_CustomMem;
-static
-#ifdef __GNUC__
-__attribute__((__unused__))
-#endif
-LZ4F_CustomMem const LZ4F_defaultCMem = { NULL, NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
-
-LZ4FLIB_STATIC_API LZ4F_cctx* LZ4F_createCompressionContext_advanced(LZ4F_CustomMem customMem, unsigned version);
-LZ4FLIB_STATIC_API LZ4F_dctx* LZ4F_createDecompressionContext_advanced(LZ4F_CustomMem customMem, unsigned version);
-
-
/*! LZ4F_getBlockSize() :
* Return, in scalar format (size_t),
* the maximum block size associated with blockSizeID.
@@ -674,6 +650,32 @@ LZ4FLIB_STATIC_API size_t LZ4F_decompress_usingDict(
const void* dict, size_t dictSize,
const LZ4F_decompressOptions_t* decompressOptionsPtr);
+
+/*! Custom memory allocation :
+ * These prototypes make it possible to pass custom allocation/free functions.
+ * LZ4F_customMem is provided at state creation time, using LZ4F_create*_advanced() listed below.
+ * All allocation/free operations will be completed using these custom variants instead of regular <stdlib.h> ones.
+ */
+typedef void* (*LZ4F_AllocFunction) (void* opaqueState, size_t size);
+typedef void* (*LZ4F_CallocFunction) (void* opaqueState, size_t size);
+typedef void (*LZ4F_FreeFunction) (void* opaqueState, void* address);
+typedef struct {
+ LZ4F_AllocFunction customAlloc;
+ LZ4F_CallocFunction customCalloc; /* optional; when not defined, uses customAlloc + memset */
+ LZ4F_FreeFunction customFree;
+ void* opaqueState;
+} LZ4F_CustomMem;
+static
+#ifdef __GNUC__
+__attribute__((__unused__))
+#endif
+LZ4F_CustomMem const LZ4F_defaultCMem = { NULL, NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
+
+LZ4FLIB_STATIC_API LZ4F_cctx* LZ4F_createCompressionContext_advanced(LZ4F_CustomMem customMem, unsigned version);
+LZ4FLIB_STATIC_API LZ4F_dctx* LZ4F_createDecompressionContext_advanced(LZ4F_CustomMem customMem, unsigned version);
+LZ4FLIB_STATIC_API LZ4F_CDict* LZ4F_createCDict_advanced(LZ4F_CustomMem customMem, const void* dictBuffer, size_t dictSize);
+
+
#if defined (__cplusplus)
}
#endif
diff --git a/tests/frametest.c b/tests/frametest.c
index 00b8acb..ec2cb12 100644
--- a/tests/frametest.c
+++ b/tests/frametest.c
@@ -143,9 +143,9 @@ static void dummy_free(void* state, void* p)
DISPLAYLEVEL(6, "freeing memory at address %p \n", p);
free(p);
assert(t != NULL);
- DISPLAYLEVEL(5, "nb of allocated memory segments before this free : %i \n", t->nbAllocs);
- assert(t->nbAllocs > 0);
t->nbAllocs -= 1;
+ DISPLAYLEVEL(5, "nb of allocated memory segments after this free : %i \n", t->nbAllocs);
+ assert(t->nbAllocs >= 0);
}
static const LZ4F_CustomMem lz4f_cmem_test = {
@@ -595,6 +595,13 @@ int basicTests(U32 seed, double compressibility)
if (cdict == NULL) goto _output_error;
CHECK( LZ4F_createCompressionContext(&cctx, LZ4F_VERSION) );
+ DISPLAYLEVEL(3, "Testing LZ4F_createCDict_advanced : ");
+ { LZ4F_CDict* const cda = LZ4F_createCDict_advanced(lz4f_cmem_test, CNBuffer, dictSize);
+ if (cda == NULL) goto _output_error;
+ LZ4F_freeCDict(cda);
+ }
+ DISPLAYLEVEL(3, "OK \n");
+
DISPLAYLEVEL(3, "LZ4F_compressFrame_usingCDict, with NULL dict : ");
CHECK_V(cSizeNoDict,
LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,