shithub: femtolisp

ref: 991160b28f27849a616f39059f79cde0b312e01a
dir: /compress.c/

View raw version
#include "flisp.h"
#include "cvalues.h"
#include "types.h"
#include "brieflz.h"

BUILTIN("lz-pack", lz_pack)
{
	if(nargs < 1)
		argcount(nargs, 1);
	if(nargs > 2)
		argcount(nargs, 2);

	if(!isarray(args[0]))
		type_error("array", args[0]);
	uint8_t *in;
	size_t insz;
	to_sized_ptr(args[0], &in, &insz);
	int level = nargs > 1 ? tofixnum(args[1]) : 0;
	if(level < 0)
		level = 0;
	else if(level > 10)
		level = 10;

	value_t v = cvalue(cv_class(ptr(args[0])), blz_max_packed_size(insz));
	uint8_t *out = cvalue_data(v);

	size_t worksz = level > 0
		? blz_workmem_size_level(insz, level)
		: blz_workmem_size(insz);
	uint8_t *work = MEM_ALLOC(worksz);
	unsigned long n = level > 0
		? blz_pack_level(in, out, insz, work, level)
		: blz_pack(in, out, insz, work);
	MEM_FREE(work);
	if(n == BLZ_ERROR)
		lerrorf(FL(ArgError), "blz error");
	cvalue_len(v) = n;
	return v;
}

BUILTIN("lz-unpack", lz_unpack)
{
	argcount(nargs, 2);

	uint8_t *in;
	size_t insz;
	to_sized_ptr(args[0], &in, &insz);
	if(!isarray(args[0]))
		type_error("array", args[0]);
	size_t outsz = tosize(args[1]);
	value_t v = cvalue(cv_class(ptr(args[0])), outsz);
	uint8_t *out = cvalue_data(v);
	unsigned long n = blz_depack_safe(in, insz, out, outsz);
	if(n == BLZ_ERROR)
		lerrorf(FL(ArgError), "blz error");
	cvalue_len(v) = n;
	return v;
}