示例#1
0
static void write_zstd(int f, int fd, const char *arg)
{
    ZSTD_inBuffer  zin;
    ZSTD_outBuffer zout;
    size_t const inbufsz  = ZSTD_CStreamInSize();
    zin.src = malloc(inbufsz);
    zout.size = ZSTD_CStreamOutSize();
    zout.dst = malloc(zout.size);

    if (!zin.src || !zout.dst)
        goto zstd_w_no_stream;

    ZSTD_CStream* const stream = ZSTD_createCStream();
    if (!stream)
        goto zstd_w_no_stream;
    if (ZSTD_isError(ZSTD_initCStream(stream, 3)))
        goto zstd_w_error;

    size_t s;
    while ((s = read(fd, (void*)zin.src, inbufsz)) > 0)
    {
        zin.size = s;
        zin.pos = 0;
        while (zin.pos < zin.size)
        {
            zout.pos = 0;
            size_t w = ZSTD_compressStream(stream, &zout, &zin);
            if (ZSTD_isError(w))
                goto zstd_w_error;
            if (write(f, zout.dst, zout.pos) != (ssize_t)zout.pos)
                goto zstd_w_error;
        }
    }

    zout.pos = 0;
    ZSTD_endStream(stream, &zout);
    // no way to handle an error here
    write(f, zout.dst, zout.pos);

zstd_w_error:
    ZSTD_freeCStream(stream);
zstd_w_no_stream:
    free((void*)zin.src);
    free(zout.dst);
    close(f);
    close(fd);
}
示例#2
0
static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned frameSize)
{
    FILE* const fin  = fopen_orDie(fname, "rb");
    FILE* const fout = fopen_orDie(outName, "wb");
    size_t const buffInSize = ZSTD_CStreamInSize();    /* can always read one full block */
    void*  const buffIn  = malloc_orDie(buffInSize);
    size_t const buffOutSize = ZSTD_CStreamOutSize();  /* can always flush a full block */
    void*  const buffOut = malloc_orDie(buffOutSize);

    ZSTD_seekable_CStream* const cstream = ZSTD_seekable_createCStream();
    if (cstream==NULL) { fprintf(stderr, "ZSTD_seekable_createCStream() error \n"); exit(10); }
    size_t const initResult = ZSTD_seekable_initCStream(cstream, cLevel, 1, frameSize);
    if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_initCStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); }

    size_t read, toRead = buffInSize;
    while( (read = fread_orDie(buffIn, toRead, fin)) ) {
        ZSTD_inBuffer input = { buffIn, read, 0 };
        while (input.pos < input.size) {
            ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
            toRead = ZSTD_seekable_compressStream(cstream, &output , &input);   /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */
            if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_seekable_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); }
            if (toRead > buffInSize) toRead = buffInSize;   /* Safely handle case when `buffInSize` is manually changed to a value < ZSTD_CStreamInSize()*/
            fwrite_orDie(buffOut, output.pos, fout);
        }
    }

    while (1) {
        ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
        size_t const remainingToFlush = ZSTD_seekable_endStream(cstream, &output);   /* close stream */
        if (ZSTD_isError(remainingToFlush)) { fprintf(stderr, "ZSTD_seekable_endStream() error : %s \n", ZSTD_getErrorName(remainingToFlush)); exit(13); }
        fwrite_orDie(buffOut, output.pos, fout);
        if (!remainingToFlush) break;
    }

    ZSTD_seekable_freeCStream(cstream);
    fclose_orDie(fout);
    fclose_orDie(fin);
    free(buffIn);
    free(buffOut);
}
示例#3
0
		ByteArray CompressFile(const FilePath& path, const int32 compressionLevel)
		{
			BinaryReader reader(path);

			if (!reader)
			{
				return ByteArray();
			}

			const size_t inputBufferSize = ZSTD_CStreamInSize();
			const auto pInputBuffer = std::make_unique<Byte[]>(inputBufferSize);

			const size_t outputBufferSize = ZSTD_CStreamOutSize();
			const auto pOutputBuffer = std::make_unique<Byte[]>(outputBufferSize);

			ZSTD_CStream* const cStream = ZSTD_createCStream();

			if (!cStream)
			{
				return ByteArray();
			}

			const size_t initResult = ZSTD_initCStream(cStream, compressionLevel);

			if (ZSTD_isError(initResult))
			{
				ZSTD_freeCStream(cStream);
				return ByteArray();
			}

			size_t toRead = inputBufferSize;

			Array<Byte> buffer;

			while (const size_t read = static_cast<size_t>(reader.read(pInputBuffer.get(), toRead)))
			{
				ZSTD_inBuffer input = { pInputBuffer.get(), read, 0 };

				while (input.pos < input.size)
				{
					ZSTD_outBuffer output = { pOutputBuffer.get(), outputBufferSize, 0 };
					
					toRead = ZSTD_compressStream(cStream, &output, &input);
					
					if (ZSTD_isError(toRead))
					{
						ZSTD_freeCStream(cStream);
						return ByteArray();
					}

					if (toRead > inputBufferSize)
					{
						toRead = inputBufferSize;
					}

					buffer.insert(buffer.end(), pOutputBuffer.get(), pOutputBuffer.get() + output.pos);
				}
			}

			ZSTD_outBuffer output = { pOutputBuffer.get(), outputBufferSize, 0 };

			const size_t remainingToFlush = ZSTD_endStream(cStream, &output);

			ZSTD_freeCStream(cStream);

			if (remainingToFlush)
			{
				return ByteArray();
			}

			buffer.insert(buffer.end(), pOutputBuffer.get(), pOutputBuffer.get() + output.pos);

			return ByteArray(std::move(buffer));
		}
示例#4
0
		bool CompressFileToFile(const FilePath& inputPath, const FilePath& outputPath, const int32 compressionLevel)
		{
			BinaryReader reader(inputPath);
			
			if (!reader)
			{
				return false;
			}

			const size_t inputBufferSize = ZSTD_CStreamInSize();
			const auto pInputBuffer = std::make_unique<Byte[]>(inputBufferSize);

			const size_t outputBufferSize = ZSTD_CStreamOutSize();
			const auto pOutputBuffer = std::make_unique<Byte[]>(outputBufferSize);

			ZSTD_CStream* const cStream = ZSTD_createCStream();

			if (!cStream)
			{
				return false;
			}

			const size_t initResult = ZSTD_initCStream(cStream, compressionLevel);

			if (ZSTD_isError(initResult))
			{
				ZSTD_freeCStream(cStream);
				return false;
			}

			size_t toRead = inputBufferSize;

			BinaryWriter writer(outputPath);

			if (!writer)
			{
				ZSTD_freeCStream(cStream);
				return false;
			}

			while (const size_t read = static_cast<size_t>(reader.read(pInputBuffer.get(), toRead)))
			{
				ZSTD_inBuffer input = { pInputBuffer.get(), read, 0 };

				while (input.pos < input.size)
				{
					ZSTD_outBuffer output = { pOutputBuffer.get(), outputBufferSize, 0 };

					toRead = ZSTD_compressStream(cStream, &output, &input);

					if (ZSTD_isError(toRead))
					{
						writer.clear();

						ZSTD_freeCStream(cStream);

						return false;
					}

					if (toRead > inputBufferSize)
					{
						toRead = inputBufferSize;
					}

					writer.write(pOutputBuffer.get(), output.pos);
				}
			}

			ZSTD_outBuffer output = { pOutputBuffer.get(), outputBufferSize, 0 };

			const size_t remainingToFlush = ZSTD_endStream(cStream, &output);

			ZSTD_freeCStream(cStream);

			if (remainingToFlush)
			{
				writer.clear();

				return false;
			}

			writer.write(pOutputBuffer.get(), output.pos);

			return true;
		}
示例#5
0
size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_CStreamOutSize(); }