From 04622b678ab6c623b63d1f69c36c22610dc920f2 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 23 Apr 2020 21:10:02 -0700 Subject: feat: started prototype of zlib wrapper --- sys/libbio/io/fasta.c | 4 + sys/libn/flate.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 sys/libbio/io/fasta.c create mode 100644 sys/libn/flate.c (limited to 'sys') diff --git a/sys/libbio/io/fasta.c b/sys/libbio/io/fasta.c new file mode 100644 index 0000000..c1358b6 --- /dev/null +++ b/sys/libbio/io/fasta.c @@ -0,0 +1,4 @@ +#include +#include +#include + diff --git a/sys/libn/flate.c b/sys/libn/flate.c new file mode 100644 index 0000000..907d958 --- /dev/null +++ b/sys/libn/flate.c @@ -0,0 +1,243 @@ +#include +#include + +#include + +typedef struct buffer +{ + union { + struct z_stream_s; + z_stream z; + }; + + ubyte buf[4098]; +} buffer; + +// ----------------------------------------------------------------------- +// Reading + +typedef struct gz·Reader +{ + io·Reader rdr; + void* impl; + + union { + struct buffer; + buffer b; + }; +} gz·Reader; + +gz·Reader* +gz·newreader(io·Reader rdr, void* r, mem·Allocator mem, void* m) +{ + error err; + gz·Reader *zrdr; + + zrdr = mem.alloc(m, 1, sizeof(*zrdr)); + + zrdr->zalloc = mem.alloc; + zrdr->zfree = mem.free; + zrdr->opaque = m; + zrdr->avail_in = rdr.read(r, 1, arrlen(zrdr->buf), zrdr->buf); + zrdr->next_in = zrdr->buf; + + err = inflateInit(&zrdr->b.z); + + switch (err) { + case Z_OK: + return zrdr; + + case Z_MEM_ERROR: + errorf("zlib: not enough memory"); + goto ERROR; + + case Z_VERSION_ERROR: + errorf("zlib: incompatible version"); + goto ERROR; + + case Z_STREAM_ERROR: + errorf("zlib: incorrect input parameters"); + goto ERROR; + + default: + errorf("zlib: unrecognized error code"); + } +ERROR: + errorf("zlib: msg: %s", zrdr->msg); + mem.free(m, zrdr); + return nil; +} + +error +gz·freereader(gz·Reader *rdr) +{ + int err; + gz·Reader zrdr; + + zrdr = *rdr; + err = inflateEnd(&zrdr.b.z); + if (err != Z_OK) { + errorf("zlib: failed to cleanup"); + return err; + } + rdr->zfree(rdr->opaque, rdr); + + return 0; +} + +int +gz·read(gz·Reader *rdr, int sz, int n, void *buf) +{ + int r; + int err; + gz·Reader zrdr; + + zrdr = *rdr; + zrdr.next_out = buf; + zrdr.avail_out = n*sz; + +READ: + err = inflate(&zrdr.b.z, Z_STREAM_END); + switch (err) { + case Z_OK: + return n; + + case Z_STREAM_END: + r = zrdr.next_out - (ubyte*)buf; + n -= r; + zrdr.avail_in = zrdr.rdr.read(zrdr.impl, 1, arrlen(zrdr.buf), zrdr.buf); + if (!zrdr.avail_in) { + return r; + } + zrdr.next_in = zrdr.buf; + goto READ; + + case Z_NEED_DICT: + errorf("zlib: need input dictionary"); + goto ERROR; + + case Z_STREAM_ERROR: + errorf("zlib: inconsistent stream structure"); + goto ERROR; + } +ERROR: + gz·freereader(rdr); + return -1; +} + +// ----------------------------------------------------------------------- +// Writing + +struct gz·Writer +{ + io·Writer wtr; + void* impl; + + union { + struct buffer; + buffer b; + }; +}; + +gz·Writer* +gz·newwriter(io·Writer wtr, void* w, mem·Allocator mem, void* m) +{ + error err; + gz·Writer *zwtr; + + zwtr = mem.alloc(m, 1, sizeof(*zwtr)); + zwtr->zalloc = mem.alloc; + zwtr->zfree = mem.free; + zwtr->opaque = m; + zwtr->avail_in = 0; + + err = deflateInit(&zwtr->b.z, Z_DEFAULT_COMPRESSION); + + switch (err) { + case Z_OK: + return zwtr; + + case Z_MEM_ERROR: + errorf("zlib: not enough memory"); + goto ERROR; + + case Z_VERSION_ERROR: + errorf("zlib: incompatible version"); + goto ERROR; + + case Z_STREAM_ERROR: + errorf("zlib: incorrect compression level"); + goto ERROR; + + default: + errorf("zlib: unrecognized error code"); + } +ERROR: + errorf("zlib: msg: %s", zwtr->msg); + mem.free(m, zwtr); + return nil; +} + +error +gz·freewriter(gz·Writer *wtr) +{ + int err; + gz·Writer zwtr; + + zwtr = *wtr; + err = deflateEnd(&zwtr.b.z); + if (err != Z_OK) { + errorf("zlib: failed to cleanup"); + return err; + } + zwtr.zfree(zwtr.opaque, wtr); + + return 0; +} + +int +gz·write(gz·Writer *wtr, int sz, int n, void *buf) +{ + int r; + int err; + gz·Writer zwtr; + + zwtr = *wtr; + zwtr.next_out = buf; +DEFLATE: + zwtr.avail_out = n*sz; + err = deflate(&zwtr.z, Z_NO_FLUSH); + + switch (err) { + case Z_STREAM_END: + return n; + + case Z_OK: + r = (zwtr.next_out - (ubyte*)buf)/sz; + n -= r; + if (!n) { + return r; + } + buf += n; + goto DEFLATE; + + case Z_STREAM_ERROR: + errorf("zlib: bad input"); + goto ERROR; + + case Z_BUF_ERROR: + if (!zwtr.avail_in) { + zwtr.avail_in += zwtr.wtr.write(zwtr.impl, 1, arrlen(zwtr.buf), buf); + if (!zwtr.avail_in) { + errorf("reader: failed read"); + goto ERROR; + } + goto DEFLATE; + } + } + + return 0; +ERROR: + errorf("zlib: %s", zwtr.msg); + return -1; +} -- cgit v1.2.1