shithub: sl

ref: a70379d7e4b822f532fb0a8ccdd1624a90b64a68
dir: /src/compress.c/

View raw version
#include "sl.h"
#include "compress.h"
#include "cvalues.h"
#include "types.h"
#include "brieflz.h"

static sl_v sl_sizesym, sl_tosym;

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

	if(!isarr(args[0]))
		type_error("arr", args[0]);
	u8int *in;
	usize 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;

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

	usize worksz = level > 0
		? blz_workmem_size_level(insz, level)
		: blz_workmem_size(insz);
	u8int *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(sl_errarg, "blz error");
	cvalue_len(v) = n;
	return v;
}

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

	u8int *in;
	usize insz;
	to_sized_ptr(args[0], &in, &insz);
	if(!isarr(args[0]))
		type_error("arr", args[0]);
	usize outsz;
	u8int *out;
	sl_v v;
	if(args[1] == sl_sizesym){
		outsz = tosize(args[2]);
		v = cvalue(cv_class(ptr(args[0])), outsz);
		out = cvalue_data(v);
	}else if(args[1] == sl_tosym){
		v = args[2];
		to_sized_ptr(v, &out, &outsz);
	}else{
		lerrorf(sl_errarg, "either :size or :to must be specified");
	}
	unsigned long n = blz_depack_safe(in, insz, out, outsz);
	if(n == BLZ_ERROR)
		lerrorf(sl_errarg, "blz error");
	cvalue_len(v) = n;
	return v;
}

void
compress_init(void)
{
	sl_sizesym = mk_csym(":size");
	sl_tosym = mk_csym(":to");
}