void test_compress(file* outfp, file* inpfp)
{
    lz4_streamhc_t lz4stream_body = { 0 };
    lz4_streamhc_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_compresshc_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);
}
Beispiel #2
0
static void allocate_lz4(void)
{
	big_oops_buf_sz = lz4_compressbound(psinfo->bufsize);
	big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
	if (big_oops_buf) {
		workspace = kmalloc(LZ4_MEM_COMPRESS, GFP_KERNEL);
		if (!workspace) {
			pr_err("No memory for compression workspace; skipping compression\n");
			kfree(big_oops_buf);
			big_oops_buf = NULL;
		}
	} else {
		pr_err("No memory for uncompressed data; skipping compression\n");
		workspace = NULL;
	}
}
void test_decompress(file* outfp, file* inpfp)
{
    static char decbuf[dec_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);
            size_t r1;
            if(r0 != 1 || cmpbytes <= 0)
                break;

            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 >= dec_buffer_bytes - message_max_bytes)
                decoffset = 0;
        }
    }
}
static inline int unlz4(u8 *input, int in_len,
				int (*fill) (void *, unsigned int),
				int (*flush) (void *, unsigned int),
				u8 *output, int *posp,
				void (*error) (char *x))
{
	int ret = -1;
	size_t chunksize = 0;
	size_t uncomp_chunksize = LZ4_DEFAULT_UNCOMPRESSED_CHUNK_SIZE;
	u8 *inp;
	u8 *inp_start;
	u8 *outp;
	int size = in_len;
#ifdef PREBOOT
	size_t out_len = get_unaligned_le32(input + in_len);
#endif
	size_t dest_len;


	if (output) {
		outp = output;
	} else if (!flush) {
		error("NULL output pointer and no flush function provided");
		goto exit_0;
	} else {
		outp = MALLOC(uncomp_chunksize);
		if (!outp) {
			error("Could not allocate output buffer");
			goto exit_0;
		}
	}

	if (input && fill) {
		error("Both input pointer and fill function provided,");
		goto exit_1;
	} else if (input) {
		inp = input;
	} else if (!fill) {
		error("NULL input pointer and missing fill function");
		goto exit_1;
	} else {
		inp = MALLOC(lz4_compressbound(uncomp_chunksize));
		if (!inp) {
			error("Could not allocate input buffer");
			goto exit_1;
		}
	}
	inp_start = inp;

	if (posp)
		*posp = 0;

	if (fill)
		fill(inp, 4);

	chunksize = get_unaligned_le32(inp);
	if (chunksize == ARCHIVE_MAGICNUMBER) {
		inp += 4;
		size -= 4;
	} else {
		error("invalid header");
		goto exit_2;
	}

	if (posp)
		*posp += 4;

	for (;;) {

		if (fill)
			fill(inp, 4);

		chunksize = get_unaligned_le32(inp);
		if (chunksize == ARCHIVE_MAGICNUMBER) {
			inp += 4;
			size -= 4;
			if (posp)
				*posp += 4;
			continue;
		}
		inp += 4;
		size -= 4;

		if (posp)
			*posp += 4;

		if (fill) {
			if (chunksize > lz4_compressbound(uncomp_chunksize)) {
				error("chunk length is longer than allocated");
				goto exit_2;
			}
			fill(inp, chunksize);
		}
#ifdef PREBOOT
		if (out_len >= uncomp_chunksize) {
			dest_len = uncomp_chunksize;
			out_len -= dest_len;
		} else
			dest_len = out_len;
		ret = lz4_decompress(inp, &chunksize, outp, dest_len);
#else
		dest_len = uncomp_chunksize;
		ret = lz4_decompress_unknownoutputsize(inp, chunksize, outp,
				&dest_len);
#endif
		if (ret < 0) {
			error("Decoding failed");
			goto exit_2;
		}

		if (flush && flush(outp, dest_len) != dest_len)
			goto exit_2;
		if (output)
			outp += dest_len;
		if (posp)
			*posp += chunksize;

		size -= chunksize;

		if (size == 0)
			break;
		else if (size < 0) {
			error("data corrupted");
			goto exit_2;
		}

		inp += chunksize;
		if (fill)
			inp = inp_start;
	}

	ret = 0;
exit_2:
	if (!input)
		FREE(inp_start);
exit_1:
	if (!output)
		FREE(outp);
exit_0:
	return ret;
}