/*===========================================
* Dependencies
*==========================================*/
-#include <stddef.h> /* size_t */
-#include <stdlib.h> /* malloc, free */
-#include <stdio.h> /* fprintf */
-#include <string.h> /* strlen */
+#include <stddef.h> /* size_t */
+#include <stdlib.h> /* malloc, free */
+#include <stdio.h> /* fprintf */
+#include <string.h> /* strlen */
+#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_decompressBound */
#include "zstd.h"
#include "zstd_errors.h"
const char* const EXPECTED; /* content is at end of file */
-int testSimpleAPI(void)
+static int testSimpleAPI(void)
{
size_t const size = strlen(EXPECTED);
char* const output = malloc(size);
return 0;
}
-int testStreamingAPI(void)
+
+static int testStreamingAPI(void)
{
+ int error_code = 0;
size_t const outBuffSize = ZSTD_DStreamOutSize();
char* const outBuff = malloc(outBuffSize);
ZSTD_DStream* const stream = ZSTD_createDStream();
}
if (stream == NULL) {
DISPLAY("ERROR: Could not create dstream\n");
+ free(outBuff);
return 1;
}
if (needsInit) {
size_t const ret = ZSTD_initDStream(stream);
if (ZSTD_isError(ret)) {
- DISPLAY("ERROR: %s\n", ZSTD_getErrorName(ret));
- return 1;
- }
- }
- {
- size_t const ret = ZSTD_decompressStream(stream, &output, &input);
+ DISPLAY("ERROR: ZSTD_initDStream: %s\n", ZSTD_getErrorName(ret));
+ error_code = 1;
+ break;
+ } }
+
+ { size_t const ret = ZSTD_decompressStream(stream, &output, &input);
if (ZSTD_isError(ret)) {
- DISPLAY("ERROR: %s\n", ZSTD_getErrorName(ret));
- return 1;
+ DISPLAY("ERROR: ZSTD_decompressStream: %s\n", ZSTD_getErrorName(ret));
+ error_code = 1;
+ break;
}
if (ret == 0) {
needsInit = 1;
- }
- }
+ } }
if (memcmp(outBuff, EXPECTED + outputPos, output.pos) != 0) {
DISPLAY("ERROR: Wrong decoded output produced\n");
- return 1;
+ error_code = 1;
+ break;
}
outputPos += output.pos;
if (input.pos == input.size && output.pos < output.size) {
free(outBuff);
ZSTD_freeDStream(stream);
- DISPLAY("Streaming API OK\n");
+ if (error_code == 0) DISPLAY("Streaming API OK\n");
+ return error_code;
+}
+
+static int testFrameDecoding(void)
+{
+ if (strlen(EXPECTED) > ZSTD_decompressBound(COMPRESSED, COMPRESSED_SIZE)) {
+ DISPLAY("ERROR: ZSTD_decompressBound: decompressed bound too small\n");
+ return 1;
+ }
+ { const char* ip = COMPRESSED;
+ size_t remainingSize = COMPRESSED_SIZE;
+ while (1) {
+ size_t frameSize = ZSTD_findFrameCompressedSize(ip, remainingSize);
+ if (ZSTD_isError(frameSize)) {
+ DISPLAY("ERROR: ZSTD_findFrameCompressedSize: %s\n", ZSTD_getErrorName(frameSize));
+ return 1;
+ }
+ if (frameSize > remainingSize) {
+ DISPLAY("ERROR: ZSTD_findFrameCompressedSize: expected frameSize to align with src buffer");
+ return 1;
+ }
+ ip += frameSize;
+ remainingSize -= frameSize;
+ if (remainingSize == 0) break;
+ }
+ }
+ DISPLAY("Frame Decoding OK\n");
return 0;
}
int main(void)
{
- int ret;
-
- ret = testSimpleAPI();
- if (ret) return ret;
- ret = testStreamingAPI();
- if (ret) return ret;
+ { int const ret = testSimpleAPI();
+ if (ret) return ret; }
+ { int const ret = testStreamingAPI();
+ if (ret) return ret; }
+ { int const ret = testFrameDecoding();
+ if (ret) return ret; }
DISPLAY("OK\n");
-
return 0;
}