From 9695ea005d4af93dcd60f74f10fd3c54499a182f Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 11 Nov 2021 16:31:58 -0800 Subject: chore: split up base library into individual files for smaller binaries --- sys/base/flate/internal.h | 39 +++++++++++++++++++++++++++++++ sys/base/flate/read.c | 41 ++++++++++++++++++++++++++++++++ sys/base/flate/reader.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ sys/base/flate/rules.mk | 6 +++++ sys/base/flate/write.c | 48 ++++++++++++++++++++++++++++++++++++++ sys/base/flate/writer.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 250 insertions(+) create mode 100644 sys/base/flate/internal.h create mode 100644 sys/base/flate/read.c create mode 100644 sys/base/flate/reader.c create mode 100644 sys/base/flate/rules.mk create mode 100644 sys/base/flate/write.c create mode 100644 sys/base/flate/writer.c (limited to 'sys/base/flate') diff --git a/sys/base/flate/internal.h b/sys/base/flate/internal.h new file mode 100644 index 0000000..794c7c2 --- /dev/null +++ b/sys/base/flate/internal.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + +#include + +typedef struct buffer +{ + union { + struct z_stream_s; + z_stream z; + }; + + ubyte buf[4098]; +} buffer; + +typedef struct flate·Reader +{ + io·Reader rdr; + void* impl; + + union { + struct buffer; + buffer b; + }; +} flate·Reader; + +typedef struct flate·Writer +{ + io·Writer wtr; + void* impl; + + union { + struct buffer; + buffer b; + }; +} flate·Writer; + diff --git a/sys/base/flate/read.c b/sys/base/flate/read.c new file mode 100644 index 0000000..9a42070 --- /dev/null +++ b/sys/base/flate/read.c @@ -0,0 +1,41 @@ +#include "internal.h" + +int +flate·read(flate·Reader *rdr, int sz, int n, void *buf) +{ + int r; + int err; + flate·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: + flate·closereader(rdr); + return -1; +} diff --git a/sys/base/flate/reader.c b/sys/base/flate/reader.c new file mode 100644 index 0000000..84f0d80 --- /dev/null +++ b/sys/base/flate/reader.c @@ -0,0 +1,59 @@ +#include "internal.h" + +flate·Reader* +flate·openreader(io·Reader rdr, void* r, mem·Allocator mem, void* m) +{ + error err; + flate·Reader *zrdr; + + zrdr = mem.alloc(m, 1, sizeof(*zrdr)); + + zrdr->zalloc = (void *(*)(void *, unsigned int, unsigned int))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 +flate·closereader(flate·Reader *rdr) +{ + int err; + flate·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; +} diff --git a/sys/base/flate/rules.mk b/sys/base/flate/rules.mk new file mode 100644 index 0000000..54d8c14 --- /dev/null +++ b/sys/base/flate/rules.mk @@ -0,0 +1,6 @@ +SRCS_$(d)+=\ + $(d)/flate/read.c\ + $(d)/flate/reader.c\ + $(d)/flate/write.c\ + $(d)/flate/writer.c\ + $(d)/flate/writer.c\ diff --git a/sys/base/flate/write.c b/sys/base/flate/write.c new file mode 100644 index 0000000..3f07b94 --- /dev/null +++ b/sys/base/flate/write.c @@ -0,0 +1,48 @@ +#include "internal.h" + +int +flate·write(flate·Writer *wtr, int sz, int n, void *buf) +{ + int r; + int err; + flate·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; +} diff --git a/sys/base/flate/writer.c b/sys/base/flate/writer.c new file mode 100644 index 0000000..f339ae0 --- /dev/null +++ b/sys/base/flate/writer.c @@ -0,0 +1,57 @@ +#include "internal.h" + +flate·Writer* +flate·openwriter(io·Writer wtr, void* w, mem·Allocator mem, void* m) +{ + error err; + flate·Writer *zwtr; + + zwtr = mem.alloc(m, 1, sizeof(*zwtr)); + zwtr->zalloc = (void *(*)(void *, unsigned int, unsigned int))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 +flate·closewriter(flate·Writer *wtr) +{ + int err; + flate·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; +} -- cgit v1.2.1