diff options
author | Yann Collet <yann.collet.73@gmail.com> | 2014-08-26 13:27:22 (GMT) |
---|---|---|
committer | Yann Collet <yann.collet.73@gmail.com> | 2014-08-26 13:27:22 (GMT) |
commit | 43465ae8ff2ff07020ef6183172c4160ec6415fb (patch) | |
tree | defb02aa2031b29a67ba0f9bd0dd854e8d8be363 /examples/blockStreaming_ringBuffer.c | |
parent | 18392cd5e186ae2d3420130dc0f5451b4d916e3e (diff) | |
download | lz4-43465ae8ff2ff07020ef6183172c4160ec6415fb.zip lz4-43465ae8ff2ff07020ef6183172c4160ec6415fb.tar.gz lz4-43465ae8ff2ff07020ef6183172c4160ec6415fb.tar.bz2 |
Added : examples from Takayuki Matsuoka
Diffstat (limited to 'examples/blockStreaming_ringBuffer.c')
-rw-r--r-- | examples/blockStreaming_ringBuffer.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/examples/blockStreaming_ringBuffer.c b/examples/blockStreaming_ringBuffer.c new file mode 100644 index 0000000..725e375 --- /dev/null +++ b/examples/blockStreaming_ringBuffer.c @@ -0,0 +1,186 @@ +// LZ4 streaming API example : ring buffer +// Copyright : Takayuki Matsuoka + + +#define _CRT_SECURE_NO_WARNINGS // for MSVC +#include "lz4.h" + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +enum { + MESSAGE_MAX_BYTES = 1024, + RING_BUFFER_BYTES = 1024 * 256 + MESSAGE_MAX_BYTES, + DICT_BYTES = 65536, +}; + + +size_t write_int32(FILE* fp, int32_t i) { + return fwrite(&i, sizeof(i), 1, fp); +} + +size_t write_bin(FILE* fp, const void* array, int arrayBytes) { + return fwrite(array, 1, arrayBytes, fp); +} + +size_t read_int32(FILE* fp, int32_t* i) { + return fread(i, sizeof(*i), 1, fp); +} + +size_t read_bin(FILE* fp, void* array, int arrayBytes) { + return fread(array, 1, arrayBytes, fp); +} + + +void test_compress(FILE* outFp, FILE* inpFp) +{ + LZ4_stream_t lz4Stream_body = { 0 }; + LZ4_stream_t* lz4Stream = &lz4Stream_body; + + static char inpBuf[RING_BUFFER_BYTES]; + int inpOffset = 0; + + for(;;) { + // Read random length ([1,MESSAGE_MAX_BYTES]) data to the ring buffer. + char* const inpPtr = &inpBuf[inpOffset]; + const int randomLength = (rand() % MESSAGE_MAX_BYTES) + 1; + const int inpBytes = (int) read_bin(inpFp, inpPtr, randomLength); + if (0 == inpBytes) break; + + { + char cmpBuf[LZ4_COMPRESSBOUND(MESSAGE_MAX_BYTES)]; + const int cmpBytes = LZ4_compress_continue(lz4Stream, inpPtr, cmpBuf, inpBytes); + if(cmpBytes <= 0) break; + write_int32(outFp, cmpBytes); + write_bin(outFp, cmpBuf, cmpBytes); + + inpOffset += inpBytes; + + // Wraparound the ringbuffer offset + if(inpOffset >= RING_BUFFER_BYTES - MESSAGE_MAX_BYTES) inpOffset = 0; + } + } + + write_int32(outFp, 0); +} + + +void test_decompress(FILE* outFp, FILE* inpFp) +{ + static char decBuf[RING_BUFFER_BYTES]; + int decOffset = 0; + LZ4_streamDecode_t lz4StreamDecode_body = { 0 }; + LZ4_streamDecode_t* lz4StreamDecode = &lz4StreamDecode_body; + + for(;;) { + int cmpBytes = 0; + char cmpBuf[LZ4_COMPRESSBOUND(MESSAGE_MAX_BYTES)]; + + { + const size_t r0 = read_int32(inpFp, &cmpBytes); + if(r0 != 1 || cmpBytes <= 0) break; + + const size_t r1 = read_bin(inpFp, cmpBuf, cmpBytes); + if(r1 != (size_t) cmpBytes) break; + } + + { + char* const decPtr = &decBuf[decOffset]; + const int decBytes = LZ4_decompress_safe_continue( + lz4StreamDecode, cmpBuf, decPtr, cmpBytes, MESSAGE_MAX_BYTES); + if(decBytes <= 0) break; + decOffset += decBytes; + write_bin(outFp, decPtr, decBytes); + + // Wraparound the ringbuffer offset + if(decOffset >= RING_BUFFER_BYTES - MESSAGE_MAX_BYTES) decOffset = 0; + } + } +} + + +int compare(FILE* f0, FILE* f1) +{ + int result = 0; + + while(0 == result) { + char b0[65536]; + char b1[65536]; + const size_t r0 = fread(b0, 1, sizeof(b0), f0); + const size_t r1 = fread(b1, 1, sizeof(b1), f1); + + result = (int) r0 - (int) r1; + + if(0 == r0 || 0 == r1) { + break; + } + if(0 == result) { + result = memcmp(b0, b1, r0); + } + } + + return result; +} + + +int main(int argc, char** argv) +{ + char inpFilename[256] = { 0 }; + char lz4Filename[256] = { 0 }; + char decFilename[256] = { 0 }; + + if(argc < 2) { + printf("Please specify input filename\n"); + return 0; + } + + sprintf(inpFilename, "%s", argv[1]); + sprintf(lz4Filename, "%s.lz4s-%d", argv[1], 0); + sprintf(decFilename, "%s.lz4s-%d.dec", argv[1], 0); + + printf("inp = [%s]\n", inpFilename); + printf("lz4 = [%s]\n", lz4Filename); + printf("dec = [%s]\n", decFilename); + + // compress + { + FILE* inpFp = fopen(inpFilename, "rb"); + FILE* outFp = fopen(lz4Filename, "wb"); + + test_compress(outFp, inpFp); + + fclose(outFp); + fclose(inpFp); + } + + // decompress + { + FILE* inpFp = fopen(lz4Filename, "rb"); + FILE* outFp = fopen(decFilename, "wb"); + + test_decompress(outFp, inpFp); + + fclose(outFp); + fclose(inpFp); + } + + // verify + { + FILE* inpFp = fopen(inpFilename, "rb"); + FILE* decFp = fopen(decFilename, "rb"); + + const int cmp = compare(inpFp, decFp); + if(0 == cmp) { + printf("Verify : OK\n"); + } else { + printf("Verify : NG\n"); + } + + fclose(decFp); + fclose(inpFp); + } + + return 0; +} |