Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808#include <compat.h>
#include <stdlib.h>#include <string.h>#include <zlib.h>
#include "ant.h"#include "ptr.h"#include "errors.h"#include "internal.h"
#include "silver/engine.h"#include "streams/brotli.h"#include "modules/buffer.h"#include "modules/events.h"#include "modules/symbol.h"#include "modules/zlib.h"
#define ZLIB_CHUNK 16384#define ZLIB_STREAM_TAG 0x5A4C4942u
typedef enum { ZLIB_KIND_GZIP, ZLIB_KIND_GUNZIP, ZLIB_KIND_DEFLATE, ZLIB_KIND_INFLATE, ZLIB_KIND_DEFLATE_RAW, ZLIB_KIND_INFLATE_RAW, ZLIB_KIND_UNZIP, ZLIB_KIND_BROTLI_COMPRESS, ZLIB_KIND_BROTLI_DECOMPRESS,} zlib_kind_t;
typedef struct zlib_stream_s { z_stream strm; brotli_stream_state_t *brotli; ant_value_t obj; ant_t *js; zlib_kind_t kind; uint32_t bytes_written; bool initialized; bool ended; bool destroyed; struct zlib_stream_s *next_active;} zlib_stream_t;
static ant_value_t g_transform_proto = 0;static zlib_stream_t *g_active_streams = NULL;
static bool zlib_kind_is_compress(zlib_kind_t k) { return k == ZLIB_KIND_GZIP || k == ZLIB_KIND_DEFLATE || k == ZLIB_KIND_DEFLATE_RAW || k == ZLIB_KIND_BROTLI_COMPRESS;}
static int zlib_window_bits(zlib_kind_t k) { switch (k) { case ZLIB_KIND_GZIP: return 15 + 16; case ZLIB_KIND_GUNZIP: return 15 + 32; case ZLIB_KIND_UNZIP: return 15 + 32; case ZLIB_KIND_DEFLATE: return 15; case ZLIB_KIND_INFLATE: return 15; case ZLIB_KIND_DEFLATE_RAW: return -15; case ZLIB_KIND_INFLATE_RAW: return -15; default: return 15; }}
static ant_value_t pick_callback(ant_value_t *args, int nargs) { if (nargs > 2 && is_callable(args[2])) return args[2]; if (nargs > 1 && is_callable(args[1])) return args[1]; return js_mkundef();}
static zlib_stream_t *zlib_stream_ptr(ant_value_t obj) { if (!js_check_native_tag(obj, ZLIB_STREAM_TAG)) return NULL; return (zlib_stream_t *)js_get_native_ptr(obj);}
static void zlib_add_active(zlib_stream_t *st) { st->next_active = g_active_streams; g_active_streams = st;}
static void zlib_remove_active(zlib_stream_t *st) { zlib_stream_t **it; for (it = &g_active_streams; *it; it = &(*it)->next_active) { if (*it == st) { *it = st->next_active; st->next_active = NULL; return; }}}
static void zlib_stream_release(zlib_stream_t *st) { if (!st) return; if (st->brotli) { brotli_stream_state_destroy(st->brotli); st->brotli = NULL; } else if (st->initialized) { if (zlib_kind_is_compress(st->kind)) deflateEnd(&st->strm); else inflateEnd(&st->strm); st->initialized = false; }}
static ant_value_t zlib_make_buffer(ant_t *js, const uint8_t *data, size_t len) { ArrayBufferData *ab = create_array_buffer_data(len); if (!ab) return js_mkerr(js, "out of memory"); if (data && len > 0) memcpy(ab->data, data, len); return create_typed_array(js, TYPED_ARRAY_UINT8, ab, 0, len, "Buffer");}
static void zlib_emit_data(ant_t *js, ant_value_t obj, const uint8_t *data, size_t len) { ant_value_t buf = zlib_make_buffer(js, data, len); if (!is_err(buf)) eventemitter_emit_args(js, obj, "data", &buf, 1);}
typedef struct { ant_t *js; ant_value_t obj; } brotli_emit_ctx_t;typedef struct { ant_t *js; ant_value_t arr; bool error; } brotli_collect_ctx_t;
static int brotli_emit_cb(void *ctx, const uint8_t *chunk, size_t len) { brotli_emit_ctx_t *ec = (brotli_emit_ctx_t *)ctx; zlib_emit_data(ec->js, ec->obj, chunk, len); return 0;}
static int brotli_collect_cb(void *ctx, const uint8_t *chunk, size_t len) { brotli_collect_ctx_t *ec = (brotli_collect_ctx_t *)ctx; ant_value_t buf = zlib_make_buffer(ec->js, chunk, len); if (is_err(buf)) { ec->error = true; return -1; } js_arr_push(ec->js, ec->arr, buf); return 0;}
static ant_value_t zlib_do_process( ant_t *js, zlib_stream_t *st, const uint8_t *input, size_t input_len, bool finish) { if (st->destroyed || st->ended) return js_mkundef();
if (st->brotli) { brotli_emit_ctx_t ctx = { js, st->obj }; int rc; if (finish) { rc = brotli_stream_finish(st->brotli, brotli_emit_cb, &ctx); } else { rc = brotli_stream_process(st->brotli, input, input_len, brotli_emit_cb, &ctx); } if (rc < 0) return js_mkerr(js, "brotli operation failed"); return js_mkundef(); }
bool compress = zlib_kind_is_compress(st->kind); int flush = finish ? Z_FINISH : Z_NO_FLUSH; uint8_t out[ZLIB_CHUNK];
if (!finish) { st->strm.next_in = (Bytef *)input; st->strm.avail_in = (uInt)input_len; } else { st->strm.next_in = NULL; st->strm.avail_in = 0; }
int ret; do { st->strm.next_out = out; st->strm.avail_out = ZLIB_CHUNK;
if (compress) { ret = deflate(&st->strm, flush); if (ret == Z_STREAM_ERROR) return js_mkerr(js, "zlib deflate error"); } else { ret = inflate(&st->strm, flush == Z_FINISH ? Z_SYNC_FLUSH : flush); if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) return js_mkerr(js, "zlib inflate error"); }
size_t have = ZLIB_CHUNK - st->strm.avail_out; if (have > 0) zlib_emit_data(js, st->obj, out, have); if (ret == Z_STREAM_END) break; } while (st->strm.avail_out == 0);
return js_mkundef();}
static ant_value_t zlib_process_chunk_sync( ant_t *js, zlib_stream_t *st, const uint8_t *input, size_t input_len, int flush_flag) { ant_value_t arr = js_mkarr(js);
if (st->brotli) { brotli_collect_ctx_t ctx = { js, arr, false }; int rc = 0; if (input && input_len > 0) rc = brotli_stream_process(st->brotli, input, input_len, brotli_collect_cb, &ctx); if (rc >= 0 && flush_flag == Z_FINISH) rc = brotli_stream_finish(st->brotli, brotli_collect_cb, &ctx); if (rc < 0 || ctx.error) return js_mkerr(js, "brotli operation failed"); return arr; }
bool compress = zlib_kind_is_compress(st->kind); uint8_t out[ZLIB_CHUNK];
st->strm.next_in = input ? (Bytef *)input : NULL; st->strm.avail_in = input ? (uInt)input_len : 0;
int ret; do { st->strm.next_out = out; st->strm.avail_out = ZLIB_CHUNK;
if (compress) { ret = deflate(&st->strm, flush_flag); if (ret == Z_STREAM_ERROR) return js_mkerr(js, "zlib deflate error"); } else { ret = inflate(&st->strm, flush_flag); if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) return js_mkerr(js, "zlib inflate error"); }
size_t have = ZLIB_CHUNK - st->strm.avail_out; if (have > 0) { ant_value_t buf = zlib_make_buffer(js, out, have); if (is_err(buf)) return buf; js_arr_push(js, arr, buf); } if (ret == Z_STREAM_END) break; } while (st->strm.avail_out == 0);
return arr;}
static ant_value_t js_zlib_process_chunk(ant_t *js, ant_value_t *args, int nargs) { zlib_stream_t *st = zlib_stream_ptr(js_getthis(js)); if (!st) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid zlib stream"); if (st->destroyed || st->ended) return js_mkarr(js);
const uint8_t *input = NULL; size_t input_len = 0; if (nargs >= 1 && is_object_type(args[0])) buffer_source_get_bytes(js, args[0], &input, &input_len);
int flush_flag = Z_NO_FLUSH; if (nargs >= 2 && vtype(args[1]) == T_NUM) flush_flag = (int)js_getnum(args[1]);
return zlib_process_chunk_sync(js, st, input, input_len, flush_flag);}
static ant_value_t js_zlib_write(ant_t *js, ant_value_t *args, int nargs) { zlib_stream_t *st = zlib_stream_ptr(js_getthis(js)); if (!st) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid zlib stream"); if (st->destroyed) return js_false; if (st->ended) return js_false;
if (nargs < 1 || vtype(args[0]) == T_UNDEF || vtype(args[0]) == T_NULL) return js_true;
const uint8_t *bytes = NULL; size_t len = 0;
if (is_object_type(args[0])) { buffer_source_get_bytes(js, args[0], &bytes, &len); }
if (!bytes) { size_t slen = 0; char *s = js_getstr(js, args[0], &slen); if (s) { bytes = (const uint8_t *)s; len = slen; } }
if (!bytes || len == 0) return js_true; st->bytes_written += (uint32_t)len;
ant_value_t r = zlib_do_process(js, st, bytes, len, false); if (is_err(r)) { eventemitter_emit_args(js, st->obj, "error", &r, 1); return js_false; }
ant_value_t cb = pick_callback(args, nargs); if (is_callable(cb)) { ant_value_t null_val = js_mknull(); sv_vm_call(js->vm, js, cb, js_mkundef(), &null_val, 1, NULL, false); }
return js_true;}
static ant_value_t js_zlib_end(ant_t *js, ant_value_t *args, int nargs) { zlib_stream_t *st = zlib_stream_ptr(js_getthis(js)); ant_value_t self = js_getthis(js);
if (!st) return js_mkerr_typed(js, JS_ERR_TYPE, "Invalid zlib stream"); if (st->destroyed || st->ended) return self;
if (nargs > 0 && vtype(args[0]) != T_UNDEF && vtype(args[0]) != T_NULL) { ant_value_t write_args[1] = { args[0] }; js_zlib_write(js, write_args, 1); }
st->ended = true; ant_value_t r = zlib_do_process(js, st, NULL, 0, true);
if (is_err(r)) { eventemitter_emit_args(js, st->obj, "error", &r, 1); return self; }
eventemitter_emit_args(js, st->obj, "end", NULL, 0); eventemitter_emit_args(js, st->obj, "finish", NULL, 0); eventemitter_emit_args(js, st->obj, "close", NULL, 0);
ant_value_t cb = pick_callback(args, nargs); if (is_callable(cb)) sv_vm_call(js->vm, js, cb, js_mkundef(), NULL, 0, NULL, false);
return self;}
static ant_value_t js_zlib_destroy(ant_t *js, ant_value_t *args, int nargs) { zlib_stream_t *st = zlib_stream_ptr(js_getthis(js)); ant_value_t self = js_getthis(js);
if (!st || st->destroyed) return self; st->destroyed = true; zlib_stream_release(st);
if (nargs > 0 && !js_truthy(js, args[0])) { ant_value_t null_val = js_mknull(); eventemitter_emit_args(js, st->obj, "error", &null_val, 1); }
eventemitter_emit_args(js, st->obj, "close", NULL, 0); return self;}
static ant_value_t js_zlib_pause(ant_t *js, ant_value_t *args, int nargs) { return js_getthis(js);}
static ant_value_t js_zlib_resume(ant_t *js, ant_value_t *args, int nargs) { return js_getthis(js);}
static ant_value_t js_zlib_unpipe(ant_t *js, ant_value_t *args, int nargs) { return js_getthis(js);}
static ant_value_t pipe_on_data(ant_t *js, ant_value_t *args, int nargs) { ant_value_t fn = js_getcurrentfunc(js); ant_value_t dest = js_get_slot(fn, SLOT_DATA); ant_value_t write_fn = js_get(js, dest, "write"); if (is_callable(write_fn) && nargs > 0) sv_vm_call(js->vm, js, write_fn, dest, args, 1, NULL, false); return js_mkundef();}
static ant_value_t pipe_on_end(ant_t *js, ant_value_t *args, int nargs) { ant_value_t fn = js_getcurrentfunc(js); ant_value_t dest = js_get_slot(fn, SLOT_DATA); ant_value_t end_fn = js_get(js, dest, "end"); if (is_callable(end_fn)) sv_vm_call(js->vm, js, end_fn, dest, NULL, 0, NULL, false); return js_mkundef();}
static ant_value_t js_zlib_pipe(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1 || !is_object_type(args[0])) return js_mkundef(); ant_value_t self = js_getthis(js); ant_value_t dest = args[0];
ant_value_t data_handler = js_heavy_mkfun(js, pipe_on_data, dest); ant_value_t end_handler = js_heavy_mkfun(js, pipe_on_end, dest);
eventemitter_add_listener(js, self, "data", data_handler, false); eventemitter_add_listener(js, self, "end", end_handler, true);
return dest;}
static ant_value_t js_zlib_get_bytes_written(ant_t *js, ant_value_t *args, int nargs) { zlib_stream_t *st = zlib_stream_ptr(js_getthis(js)); if (!st) return js_mknum(0); return js_mknum((double)st->bytes_written);}
static ant_value_t zlib_create_stream(ant_t *js, zlib_kind_t kind) { bool compress = zlib_kind_is_compress(kind);
zlib_stream_t *st = calloc(1, sizeof(zlib_stream_t)); if (!st) return js_mkerr(js, "out of memory");
st->kind = kind; st->js = js;
if (kind == ZLIB_KIND_BROTLI_COMPRESS || kind == ZLIB_KIND_BROTLI_DECOMPRESS) { st->brotli = brotli_stream_state_new(kind == ZLIB_KIND_BROTLI_DECOMPRESS); if (!st->brotli) { free(st); return js_mkerr(js, "brotli init failed"); } st->initialized = true; } else { int wbits = zlib_window_bits(kind); int ret; if (compress) { ret = deflateInit2(&st->strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY); } else ret = inflateInit2(&st->strm, wbits);
if (ret != Z_OK) { free(st); return js_mkerr(js, "zlib init failed"); } st->initialized = true; }
ant_value_t obj = js_mkobj(js); if (is_object_type(g_transform_proto)) js_set_proto_init(obj, g_transform_proto);
js_set_native_ptr(obj, st); js_set_native_tag(obj, ZLIB_STREAM_TAG);
js_set(js, obj, "readable", js_true); js_set(js, obj, "writable", js_true); js_set(js, obj, "_processChunk", js_mkfun(js_zlib_process_chunk));
ant_value_t handle_obj = js_mkobj(js); js_set(js, handle_obj, "close", js_mkfun(js_zlib_destroy)); js_set(js, obj, "_handle", handle_obj);
st->obj = obj; zlib_add_active(st); return obj;}
static ant_value_t js_create_gzip(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_GZIP);}
static ant_value_t js_create_gunzip(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_GUNZIP);}
static ant_value_t js_create_deflate(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_DEFLATE);}
static ant_value_t js_create_inflate(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_INFLATE);}
static ant_value_t js_create_deflate_raw(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_DEFLATE_RAW);}
static ant_value_t js_create_inflate_raw(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_INFLATE_RAW);}
static ant_value_t js_create_unzip(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_UNZIP);}
static ant_value_t js_create_brotli_compress(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_BROTLI_COMPRESS);}
static ant_value_t js_create_brotli_decompress(ant_t *js, ant_value_t *args, int nargs) { return zlib_create_stream(js, ZLIB_KIND_BROTLI_DECOMPRESS);}
typedef struct { uint8_t *data; size_t len; size_t cap; int error;} zbuf_t;
static int zbuf_append(zbuf_t *b, const uint8_t *chunk, size_t n) { if (b->len + n > b->cap) { size_t newcap = b->cap ? b->cap * 2 : 4096; while (newcap < b->len + n) newcap *= 2; uint8_t *p = realloc(b->data, newcap); if (!p) { b->error = 1; return -1; } b->data = p; b->cap = newcap; } memcpy(b->data + b->len, chunk, n); b->len += n; return 0;}
static int zbuf_brotli_cb(void *ctx, const uint8_t *chunk, size_t n) { return zbuf_append((zbuf_t *)ctx, chunk, n);}
static ant_value_t zlib_sync_op( ant_t *js, zlib_kind_t kind, const uint8_t *input, size_t input_len) { zbuf_t out = {0}; uint8_t tmp[ZLIB_CHUNK]; bool compress = zlib_kind_is_compress(kind);
if (kind == ZLIB_KIND_BROTLI_COMPRESS || kind == ZLIB_KIND_BROTLI_DECOMPRESS) { brotli_stream_state_t *bs = brotli_stream_state_new(kind == ZLIB_KIND_BROTLI_DECOMPRESS); if (!bs) return js_mkerr(js, "brotli init failed"); int rc = brotli_stream_process(bs, input, input_len, zbuf_brotli_cb, &out); if (rc >= 0) rc = brotli_stream_finish(bs, zbuf_brotli_cb, &out); brotli_stream_state_destroy(bs); if (rc < 0 || out.error) { free(out.data); return js_mkerr(js, "brotli operation failed"); } ant_value_t buf = zlib_make_buffer(js, out.data, out.len); free(out.data); return buf; }
z_stream strm = {0}; int wbits = zlib_window_bits(kind); int ret;
if (compress) ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, wbits, 8, Z_DEFAULT_STRATEGY); else ret = inflateInit2(&strm, wbits); if (ret != Z_OK) return js_mkerr(js, "zlib init failed");
strm.next_in = (Bytef *)input; strm.avail_in = (uInt)input_len;
do { strm.next_out = tmp; strm.avail_out = ZLIB_CHUNK; if (compress) ret = deflate(&strm, Z_FINISH); else ret = inflate(&strm, Z_SYNC_FLUSH); if (ret == Z_STREAM_ERROR || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) { if (compress) deflateEnd(&strm); else inflateEnd(&strm); free(out.data); return js_mkerr(js, "zlib operation failed"); } size_t have = ZLIB_CHUNK - strm.avail_out; if (have > 0 && zbuf_append(&out, tmp, have) < 0) { if (compress) deflateEnd(&strm); else inflateEnd(&strm); free(out.data); return js_mkerr(js, "out of memory"); } if (ret == Z_STREAM_END) break; } while (strm.avail_out == 0 || strm.avail_in > 0);
if (compress) deflateEnd(&strm); else inflateEnd(&strm);
ant_value_t buf = zlib_make_buffer(js, out.data, out.len); free(out.data); return buf;}
static bool get_input_bytes(ant_t *js, ant_value_t val, const uint8_t **out_bytes, size_t *out_len) { if (is_object_type(val) && buffer_source_get_bytes(js, val, out_bytes, out_len)) return true; size_t slen = 0; char *s = js_getstr(js, val, &slen); if (s) { *out_bytes = (const uint8_t *)s; *out_len = slen; return true; } return false;}
static ant_value_t zlib_sync_fn(ant_t *js, ant_value_t *args, int nargs, zlib_kind_t kind) { if (nargs < 1) return js_mkerr(js, "argument required"); const uint8_t *bytes = NULL; size_t len = 0; if (!get_input_bytes(js, args[0], &bytes, &len)) return js_mkerr_typed(js, JS_ERR_TYPE, "argument must be a string or Buffer"); return zlib_sync_op(js, kind, bytes, len);}
static ant_value_t zlib_async_fn(ant_t *js, ant_value_t *args, int nargs, zlib_kind_t kind) { if (nargs < 1) return js_mkerr(js, "argument required");
const uint8_t *bytes = NULL; size_t len = 0; ant_value_t cb = pick_callback(args, nargs);
if (!get_input_bytes(js, args[0], &bytes, &len)) return js_mkerr_typed(js, JS_ERR_TYPE, "argument must be a string or Buffer");
ant_value_t result = zlib_sync_op(js, kind, bytes, len);
if (is_callable(cb)) { if (is_err(result)) { ant_value_t argv[1] = { result }; sv_vm_call(js->vm, js, cb, js_mkundef(), argv, 1, NULL, false); } else { ant_value_t null_val = js_mknull(); ant_value_t argv[2] = { null_val, result }; sv_vm_call(js->vm, js, cb, js_mkundef(), argv, 2, NULL, false); } return js_mkundef(); }
return result;}
#define ZLIB_SYNC_FN(name, kind) \ static ant_value_t js_##name##Sync(ant_t *js, ant_value_t *a, int n) { return zlib_sync_fn(js, a, n, kind); }
#define ZLIB_ASYNC_FN(name, kind) \ static ant_value_t js_##name(ant_t *js, ant_value_t *a, int n) { return zlib_async_fn(js, a, n, kind); }
ZLIB_SYNC_FN(gzip, ZLIB_KIND_GZIP)ZLIB_SYNC_FN(gunzip, ZLIB_KIND_GUNZIP)ZLIB_SYNC_FN(deflate, ZLIB_KIND_DEFLATE)ZLIB_SYNC_FN(inflate, ZLIB_KIND_INFLATE)ZLIB_SYNC_FN(deflateRaw, ZLIB_KIND_DEFLATE_RAW)ZLIB_SYNC_FN(inflateRaw, ZLIB_KIND_INFLATE_RAW)ZLIB_SYNC_FN(unzip, ZLIB_KIND_UNZIP)ZLIB_SYNC_FN(brotliCompress, ZLIB_KIND_BROTLI_COMPRESS)ZLIB_SYNC_FN(brotliDecompress, ZLIB_KIND_BROTLI_DECOMPRESS)
ZLIB_ASYNC_FN(gzip, ZLIB_KIND_GZIP)ZLIB_ASYNC_FN(gunzip, ZLIB_KIND_GUNZIP)ZLIB_ASYNC_FN(deflate, ZLIB_KIND_DEFLATE)ZLIB_ASYNC_FN(inflate, ZLIB_KIND_INFLATE)ZLIB_ASYNC_FN(deflateRaw, ZLIB_KIND_DEFLATE_RAW)ZLIB_ASYNC_FN(inflateRaw, ZLIB_KIND_INFLATE_RAW)ZLIB_ASYNC_FN(unzip, ZLIB_KIND_UNZIP)ZLIB_ASYNC_FN(brotliCompress, ZLIB_KIND_BROTLI_COMPRESS)ZLIB_ASYNC_FN(brotliDecompress, ZLIB_KIND_BROTLI_DECOMPRESS)
static ant_value_t js_zlib_crc32(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) return js_mkerr(js, "argument required");
const uint8_t *bytes = NULL; size_t len = 0; uLong init_val = 0;
if (nargs >= 2 && vtype(args[1]) == T_NUM) init_val = (uLong)js_getnum(args[1]);
if (!get_input_bytes(js, args[0], &bytes, &len)) return js_mkerr_typed(js, JS_ERR_TYPE, "argument must be a string or Buffer");
uLong crc = crc32(init_val, bytes, (uInt)len); return js_mknum((double)(uint32_t)crc);}
static ant_value_t make_constants(ant_t *js) { ant_value_t c = js_mkobj(js);
js_set(js, c, "Z_NO_FLUSH", js_mknum(Z_NO_FLUSH)); js_set(js, c, "Z_PARTIAL_FLUSH", js_mknum(Z_PARTIAL_FLUSH)); js_set(js, c, "Z_SYNC_FLUSH", js_mknum(Z_SYNC_FLUSH)); js_set(js, c, "Z_FULL_FLUSH", js_mknum(Z_FULL_FLUSH)); js_set(js, c, "Z_FINISH", js_mknum(Z_FINISH)); js_set(js, c, "Z_BLOCK", js_mknum(Z_BLOCK));
js_set(js, c, "Z_OK", js_mknum(Z_OK)); js_set(js, c, "Z_STREAM_END", js_mknum(Z_STREAM_END)); js_set(js, c, "Z_NEED_DICT", js_mknum(Z_NEED_DICT)); js_set(js, c, "Z_ERRNO", js_mknum(Z_ERRNO)); js_set(js, c, "Z_STREAM_ERROR", js_mknum(Z_STREAM_ERROR)); js_set(js, c, "Z_DATA_ERROR", js_mknum(Z_DATA_ERROR)); js_set(js, c, "Z_MEM_ERROR", js_mknum(Z_MEM_ERROR)); js_set(js, c, "Z_BUF_ERROR", js_mknum(Z_BUF_ERROR)); js_set(js, c, "Z_VERSION_ERROR", js_mknum(Z_VERSION_ERROR));
js_set(js, c, "Z_NO_COMPRESSION", js_mknum(Z_NO_COMPRESSION)); js_set(js, c, "Z_BEST_SPEED", js_mknum(Z_BEST_SPEED)); js_set(js, c, "Z_BEST_COMPRESSION", js_mknum(Z_BEST_COMPRESSION)); js_set(js, c, "Z_DEFAULT_COMPRESSION", js_mknum(Z_DEFAULT_COMPRESSION));
js_set(js, c, "Z_FILTERED", js_mknum(Z_FILTERED)); js_set(js, c, "Z_HUFFMAN_ONLY", js_mknum(Z_HUFFMAN_ONLY)); js_set(js, c, "Z_RLE", js_mknum(Z_RLE)); js_set(js, c, "Z_FIXED", js_mknum(Z_FIXED)); js_set(js, c, "Z_DEFAULT_STRATEGY", js_mknum(Z_DEFAULT_STRATEGY));
js_set(js, c, "BROTLI_OPERATION_PROCESS", js_mknum(0)); js_set(js, c, "BROTLI_OPERATION_FLUSH", js_mknum(1)); js_set(js, c, "BROTLI_OPERATION_FINISH", js_mknum(2)); js_set(js, c, "BROTLI_OPERATION_EMIT_METADATA", js_mknum(3));
js_set(js, c, "BROTLI_PARAM_MODE", js_mknum(0)); js_set(js, c, "BROTLI_MODE_GENERIC", js_mknum(0)); js_set(js, c, "BROTLI_MODE_TEXT", js_mknum(1)); js_set(js, c, "BROTLI_MODE_FONT", js_mknum(2)); js_set(js, c, "BROTLI_PARAM_QUALITY", js_mknum(1)); js_set(js, c, "BROTLI_MIN_QUALITY", js_mknum(0)); js_set(js, c, "BROTLI_MAX_QUALITY", js_mknum(11)); js_set(js, c, "BROTLI_DEFAULT_QUALITY", js_mknum(11)); js_set(js, c, "BROTLI_PARAM_LGWIN", js_mknum(2)); js_set(js, c, "BROTLI_MIN_WINDOW_BITS", js_mknum(10)); js_set(js, c, "BROTLI_MAX_WINDOW_BITS", js_mknum(24)); js_set(js, c, "BROTLI_DEFAULT_WINDOW", js_mknum(22)); js_set(js, c, "BROTLI_PARAM_SIZE_HINT", js_mknum(3)); js_set(js, c, "BROTLI_PARAM_LARGE_WINDOW", js_mknum(4)); js_set(js, c, "BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION", js_mknum(0)); js_set(js, c, "BROTLI_DECODER_PARAM_LARGE_WINDOW", js_mknum(1));
js_set(js, c, "ZSTD_e_continue", js_mknum(0)); js_set(js, c, "ZSTD_e_flush", js_mknum(1)); js_set(js, c, "ZSTD_e_end", js_mknum(2));
return c;}
static void zlib_init_proto(ant_t *js) { if (g_transform_proto) return;
ant_value_t events = events_library(js); ant_value_t ee_ctor = js_get(js, events, "EventEmitter"); ant_value_t ee_proto = js_get(js, ee_ctor, "prototype");
g_transform_proto = js_mkobj(js); js_set_proto_init(g_transform_proto, ee_proto);
js_set(js, g_transform_proto, "write", js_mkfun(js_zlib_write)); js_set(js, g_transform_proto, "end", js_mkfun(js_zlib_end)); js_set(js, g_transform_proto, "destroy", js_mkfun(js_zlib_destroy)); js_set(js, g_transform_proto, "pause", js_mkfun(js_zlib_pause)); js_set(js, g_transform_proto, "resume", js_mkfun(js_zlib_resume)); js_set(js, g_transform_proto, "unpipe", js_mkfun(js_zlib_unpipe)); js_set(js, g_transform_proto, "pipe", js_mkfun(js_zlib_pipe));
js_set_getter_desc(js, g_transform_proto, "bytesWritten", 12, js_mkfun(js_zlib_get_bytes_written), JS_DESC_C);}
static ant_value_t zlib_mkctor(ant_t *js, ant_value_t (*fn)(ant_t *, ant_value_t *, int)) { ant_value_t ctor = js_heavy_mkfun(js, fn, js_mkundef()); js_mark_constructor(ctor, true); return ctor;}
ant_value_t zlib_library(ant_t *js) { zlib_init_proto(js);
ant_value_t lib = js_mkobj(js); ant_value_t consts = make_constants(js);
js_set(js, lib, "gzip", js_mkfun(js_gzip)); js_set(js, lib, "gzipSync", js_mkfun(js_gzipSync)); js_set(js, lib, "Gzip", zlib_mkctor(js, js_create_gzip)); js_set(js, lib, "createGzip", js_mkfun(js_create_gzip));
js_set(js, lib, "gunzip", js_mkfun(js_gunzip)); js_set(js, lib, "gunzipSync", js_mkfun(js_gunzipSync)); js_set(js, lib, "Gunzip", zlib_mkctor(js, js_create_gunzip)); js_set(js, lib, "createGunzip", js_mkfun(js_create_gunzip));
js_set(js, lib, "deflate", js_mkfun(js_deflate)); js_set(js, lib, "deflateSync", js_mkfun(js_deflateSync)); js_set(js, lib, "Deflate", zlib_mkctor(js, js_create_deflate)); js_set(js, lib, "createDeflate", js_mkfun(js_create_deflate));
js_set(js, lib, "inflate", js_mkfun(js_inflate)); js_set(js, lib, "inflateSync", js_mkfun(js_inflateSync)); js_set(js, lib, "Inflate", zlib_mkctor(js, js_create_inflate)); js_set(js, lib, "createInflate", js_mkfun(js_create_inflate));
js_set(js, lib, "deflateRaw", js_mkfun(js_deflateRaw)); js_set(js, lib, "deflateRawSync", js_mkfun(js_deflateRawSync)); js_set(js, lib, "DeflateRaw", zlib_mkctor(js, js_create_deflate_raw)); js_set(js, lib, "createDeflateRaw", js_mkfun(js_create_deflate_raw));
js_set(js, lib, "inflateRaw", js_mkfun(js_inflateRaw)); js_set(js, lib, "inflateRawSync", js_mkfun(js_inflateRawSync)); js_set(js, lib, "InflateRaw", zlib_mkctor(js, js_create_inflate_raw)); js_set(js, lib, "createInflateRaw", js_mkfun(js_create_inflate_raw));
js_set(js, lib, "unzip", js_mkfun(js_unzip)); js_set(js, lib, "unzipSync", js_mkfun(js_unzipSync)); js_set(js, lib, "Unzip", zlib_mkctor(js, js_create_unzip)); js_set(js, lib, "createUnzip", js_mkfun(js_create_unzip));
js_set(js, lib, "brotliCompress", js_mkfun(js_brotliCompress)); js_set(js, lib, "brotliCompressSync", js_mkfun(js_brotliCompressSync)); js_set(js, lib, "BrotliCompress", zlib_mkctor(js, js_create_brotli_compress)); js_set(js, lib, "createBrotliCompress", js_mkfun(js_create_brotli_compress));
js_set(js, lib, "brotliDecompress", js_mkfun(js_brotliDecompress)); js_set(js, lib, "brotliDecompressSync", js_mkfun(js_brotliDecompressSync)); js_set(js, lib, "BrotliDecompress", zlib_mkctor(js, js_create_brotli_decompress)); js_set(js, lib, "createBrotliDecompress", js_mkfun(js_create_brotli_decompress)); js_set(js, lib, "default", lib); js_set(js, lib, "constants", consts); js_set(js, lib, "crc32", js_mkfun(js_zlib_crc32)); js_set_sym(js, lib, get_toStringTag_sym(), js_mkstr(js, "zlib", 4)); return lib;}
void gc_mark_zlib(ant_t *js, void (*mark)(ant_t *, ant_value_t)) { if (g_transform_proto) mark(js, g_transform_proto); for (zlib_stream_t *st = g_active_streams; st; st = st->next_active) mark(js, st->obj);}