Update a few remaining zlib source files

This commit is contained in:
Justine Tunney 2022-10-03 19:18:34 -07:00
parent 32321ab1e9
commit 01bd7d1008
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
23 changed files with 1276 additions and 778 deletions

View file

@ -124,13 +124,13 @@ Usage: turfwar.com [-dv] ARGS...\n\
!memcmp(inbuf + msg->uri.a, S, strlen(S)))
#if 1
#define LOG(...) kprintf(__VA_ARGS__)
#define LOG(...) kprintf("\r\e[K" __VA_ARGS__)
#else
#define LOG(...) (void)0
#endif
#if 0
#define DEBUG(...) kprintf(__VA_ARGS__)
#define DEBUG(...) kprintf("\r\e[K" __VA_ARGS__)
#else
#define DEBUG(...) (void)0
#endif
@ -193,6 +193,7 @@ int g_workers = WORKERS;
int g_keepalive = KEEPALIVE_MS;
nsync_note g_shutdown;
nsync_note g_terminate;
struct Recent {
nsync_mu mu;
@ -326,7 +327,7 @@ int GetClaims(struct Claims *q, struct Claim *out, int len, nsync_time dead) {
int got = 0;
nsync_mu_lock(&q->mu);
while (!q->count) {
if (nsync_cv_wait_with_deadline(&q->non_empty, &q->mu, dead, g_shutdown)) {
if (nsync_cv_wait_with_deadline(&q->non_empty, &q->mu, dead, g_terminate)) {
break; // must be ETIMEDOUT or ECANCELED
}
}
@ -756,6 +757,7 @@ void FreeAsset(struct Asset *a) {
}
void OnCtrlC(int sig) {
LOG("Got ctrl-c...\n");
nsync_note_notify(g_shutdown);
}
@ -973,8 +975,9 @@ void *ClaimWorker(void *arg) {
sqlite3 *db = 0;
sqlite3_stmt *stmt = 0;
struct Claim *v = _gc(xcalloc(BATCH_MAX, sizeof(struct Claim)));
OnlyRunOnCpu(0);
pthread_setname_np(pthread_self(), "ClaimWorker");
LOG("ClaimWorker started\n");
OnlyRunOnCpu(0);
StartOver:
CHECK_SQL(sqlite3_open("db.sqlite3", &db));
CHECK_SQL(sqlite3_exec(db, "PRAGMA journal_mode=WAL", 0, 0, 0));
@ -1004,13 +1007,14 @@ StartOver:
}
CHECK_DB(sqlite3_finalize(stmt));
CHECK_SQL(sqlite3_close(db));
LOG("ClaimWorker exiting\n");
return 0;
OnError:
sqlite3_finalize(stmt);
sqlite3_close(db);
stmt = 0;
db = 0;
usleep(1000 * 1000);
usleep(100 * 1000);
goto StartOver;
}
@ -1049,12 +1053,13 @@ void *AssetWorker(void *arg) {
}
int main(int argc, char *argv[]) {
// ShowCrashReports();
ShowCrashReports();
GetOpts(argc, argv);
__enable_threads();
sqlite3_initialize();
g_shutdown = nsync_note_new(0, nsync_time_no_deadline);
g_terminate = nsync_note_new(0, nsync_time_no_deadline);
CHECK_EQ(0, chdir("/opt/turfwar"));
putenv("TMPDIR=/opt/turfwar/tmp");
@ -1082,6 +1087,7 @@ int main(int argc, char *argv[]) {
CHECK_EQ(0, pthread_create(&nower, 0, NowWorker, 0));
pthread_t *httper = _gc(xcalloc(g_workers, sizeof(pthread_t)));
for (intptr_t i = 0; i < g_workers; ++i) {
LOG("Starting http worker #%d", i);
CHECK_EQ(0, pthread_create(httper + i, 0, HttpWorker, (void *)i));
}
@ -1090,24 +1096,35 @@ int main(int argc, char *argv[]) {
sigaction(SIGHUP, &sa, 0);
sigaction(SIGINT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
LOG("Server is ready\n");
AssetWorker(0);
// wait for threads to finish
// wait for producers to finish
LOG("Waiting for workers to finish...\n");
for (int i = 0; i < g_workers; ++i) {
CHECK_EQ(0, pthread_join(httper[i], 0));
}
CHECK_EQ(0, pthread_join(claimer, 0));
CHECK_EQ(0, pthread_join(recentr, 0));
CHECK_EQ(0, pthread_join(scorer, 0));
CHECK_EQ(0, pthread_join(nower, 0));
// wait for consumers to finish
LOG("Waiting for queue to empty...\n");
nsync_note_notify(g_terminate);
CHECK_EQ(0, pthread_join(claimer, 0));
CHECK_EQ(0, g_claims.count);
// free memory
LOG("Freeing memory...\n");
FreeAsset(&g_asset.user);
FreeAsset(&g_asset.about);
FreeAsset(&g_asset.index);
FreeAsset(&g_asset.score);
FreeAsset(&g_asset.recent);
FreeAsset(&g_asset.favicon);
nsync_note_free(g_terminate);
nsync_note_free(g_shutdown);
// CheckForMemoryLeaks();
LOG("Goodbye\n");
}

View file

@ -1,13 +1,19 @@
DESCRIPTION
zlib implements the deflate compression algorithm.
zlib implements the deflate compression algorithm
LICENSE
See LICENSE file
ORIGIN
https://chromium.googlesource.com/chromium/src/third_party/zlib
commit 8f22e90f007a7dd466b426513725c13191248315
Author: Hans Wennborg <hans@chromium.org>
Date: Fri Sep 16 16:14:51 2022 +0000
The zlib sources were obtained from Chromium's zlib fork.
https://chromium.googlesource.com/chromium/src/third_party/zlib
commit 8f22e90f007a7dd466b426513725c13191248315
Author: Hans Wennborg <hans@chromium.org>
Date: Fri Sep 16 16:14:51 2022 +0000
[zlib][fuzz] Cap the input size for zlib_inflate_with_header_fuzzer
@ -23,8 +29,23 @@ ORIGIN
NOKEYCHECK=True
GitOrigin-RevId: fd75b8c2768e7cc3a3e7a06bc563bb03c5ba0ec2
The source code for puff was obtained from zlib itself:
Origin: git@github.com:madler/zlib.git
Commit: 03614c56ad299f9b238c75aa1e66f0c08fc4fc8b
Author: Mark Adler <madler@alumni.caltech.edu>
Date: Sun Oct 30 08:36:13 2016 -0700
LOCAL CHANGES
- Changed Trace() calls to use kprintf()
- Use X86_HAVE() for runtime dispatching
- Changed Trace(stderr) calls to use kprintf()
- We use our own crc32() implementation from LIBC_STR
- Fix a Chromium Zlib regression where malloc() failures inside
deflateInit2() will result in a segmentation fault
- Provide THIRD_PARTY_ZLIB_GZ as a separate package, because it
can't work without malloc/stdio/etc. but the rest of zlib can

View file

@ -1,3 +1,6 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2011, 2016 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
@ -6,11 +9,15 @@
#include "third_party/zlib/macros.internal.h"
#include "third_party/zlib/zconf.h"
#include "third_party/zlib/zutil.internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/* @(#) $Id$ */
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
#define BASE 65521U /* largest prime smaller than 65536 */

View file

@ -1,3 +1,6 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* compress.c -- compress a memory buffer
* Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
@ -5,6 +8,11 @@
#include "third_party/zlib/internal.h"
#include "third_party/zlib/macros.internal.h"
#include "third_party/zlib/zlib.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/* @(#) $Id$ */

View file

@ -1,3 +1,6 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* crc32.c -- compute the CRC-32 of a data stream
* Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
@ -10,6 +13,11 @@
#include "third_party/zlib/deflate.internal.h"
#include "third_party/zlib/internal.h"
#include "third_party/zlib/macros.internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/* @(#) $Id$ */

View file

@ -1,83 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Copyright 1995-2017 Jean-loup Gailly and Mark Adler
Copyright 2017 The Chromium Authors
Use of this source code is governed by the BSD-style licenses that can
be found in the third_party/zlib/LICENSE file.
*/
#include "third_party/zlib/deflate.internal.h"
#include "third_party/zlib/internal.h"
#include "third_party/zlib/zutil.internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
static unsigned long gf2_matrix_times(unsigned long *mat, unsigned long vec) {
unsigned long sum;
sum = 0;
while (vec) {
if (vec & 1) sum ^= *mat;
vec >>= 1;
mat++;
}
return sum;
}
static void gf2_matrix_square(unsigned long *square, unsigned long *mat) {
int n;
for (n = 0; n < GF2_DIM; n++) {
square[n] = gf2_matrix_times(mat, mat[n]);
}
}
uLong crc32_combine(uLong crc1, uLong crc2, int64_t len2) {
int n;
unsigned long row;
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
/* degenerate case (also disallow negative lengths) */
if (len2 <= 0) return crc1;
/* put operator for one zero bit in odd */
odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
row <<= 1;
}
/* put operator for two zero bits in even */
gf2_matrix_square(even, odd);
/* put operator for four zero bits in odd */
gf2_matrix_square(odd, even);
/* apply len2 zeros to crc1 (first square will put the operator for one
zero byte, eight zero bits, in even) */
do {
/* apply zeros operator for this bit of len2 */
gf2_matrix_square(even, odd);
if (len2 & 1) crc1 = gf2_matrix_times(even, crc1);
len2 >>= 1;
/* if no more bits set, then done */
if (len2 == 0) break;
/* another iteration of the loop with odd and even swapped */
gf2_matrix_square(odd, even);
if (len2 & 1) crc1 = gf2_matrix_times(odd, crc1);
len2 >>= 1;
/* if no more bits set, then done */
} while (len2 != 0);
/* return combined crc */
crc1 ^= crc2;
return crc1;
}

View file

@ -1,3 +1,6 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
@ -9,7 +12,7 @@
#include "third_party/zlib/zutil.internal.h"
asm(".ident\t\"\\n\\n\
inflate 1.2.12.1 (zlib License)\\n\
deflate 1.2.12.1 (zlib License)\\n\
Copyright 1995-2022 Jean-loup Gailly and Mark Adler\\n\
Invented 1990 Phillip Walter Katz\"");
// clang-format off
@ -318,14 +321,19 @@ int ZEXPORT deflateInit2(strm, level, method, windowBits, memLevel, strategy)
s->window = (Bytef *) ZALLOC(strm,
s->w_size + window_padding,
2*sizeof(Byte));
/* Avoid use of unitialized values in the window, see crbug.com/1137613 and
* crbug.com/1144420 */
zmemzero(s->window, (s->w_size + window_padding) * (2 * sizeof(Byte)));
if (s->window) { /* [jart] fix regression in malloc failure checking */
zmemzero(s->window, (s->w_size + window_padding) * (2 * sizeof(Byte)));
}
s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
/* Avoid use of uninitialized value, see:
* https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11360
*/
zmemzero(s->prev, s->w_size * sizeof(Pos));
if (s->prev) { /* [jart] fix regression in malloc failure checking */
zmemzero(s->prev, s->w_size * sizeof(Pos));
}
s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
s->high_water = 0; /* nothing written to s->window yet */

View file

@ -1,22 +1,26 @@
#include "third_party/zlib/gz/gzguts.inc"
// clang-format off
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* gzclose.c -- zlib gzclose() function
* Copyright (C) 2004, 2010 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "third_party/zlib/gz/gzguts.inc"
#include "third_party/zlib/macros.internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/* gzclose() is in a separate file so that it is linked in only if it is used.
That way the other gzclose functions can be used instead to avoid linking in
unneeded compression or decompression routines. */
int gzclose(file)
int ZEXPORT gzclose(file)
gzFile file;
{
#ifndef NO_GZCOMPRESS
gz_statep state;
if (file == NULL)
@ -24,4 +28,7 @@ int gzclose(file)
state = (gz_statep)file;
return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
#else
return gzclose_r(file);
#endif
}

View file

@ -1,7 +1,9 @@
#include "libc/errno.h"
#include "libc/limits.h"
#include "libc/str/str.h"
#include "third_party/zlib/macros.internal.h"
#include "third_party/zlib/zlib.h"
#include "third_party/zlib/zutil.internal.h"
// clang-format off
/* gzguts.h -- zlib internal header definitions for gz* operations
@ -18,7 +20,6 @@
# endif
#endif
#define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
#define _POSIX_SOURCE
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
@ -81,14 +82,15 @@ typedef struct {
int direct; /* 0 if processing gzip, 1 if transparent */
/* just for reading */
int how; /* 0: get header, 1: copy, 2: decompress */
int64_t start; /* where the gzip data started, for rewinding */
z_off64_t start; /* where the gzip data started, for rewinding */
int eof; /* true if end of input file reached */
int past; /* true if read requested past end */
/* just for writing */
int level; /* compression level */
int strategy; /* compression strategy */
int reset; /* true if a reset is pending after a Z_FINISH */
/* seek request */
int64_t skip; /* amount to skip (already rewound if backwards) */
z_off64_t skip; /* amount to skip (already rewound if backwards) */
int seek; /* true if seek request pending */
/* error information */
int err; /* error code */
@ -96,20 +98,20 @@ typedef struct {
/* zlib inflate or deflate stream */
z_stream strm; /* stream structure in-place (not a pointer) */
} gz_state;
typedef gz_state *gz_statep;
typedef gz_state FAR *gz_statep;
/* shared functions */
void ZLIB_INTERNAL gz_error (gz_statep, int, const char *);
void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
#if defined UNDER_CE
char ZLIB_INTERNAL *gz_strwinerror (DWORD error);
char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
#endif
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum int64_t
value -- needed when comparing unsigned to int64_t, which is signed
(possible int64_t types off_t, off64_t, and long are all signed) */
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
value -- needed when comparing unsigned to z_off64_t, which is signed
(possible z_off64_t types off_t, off64_t, and long are all signed) */
#ifdef INT_MAX
# define GT_OFF(x) (sizeof(int) == sizeof(int64_t) && (x) > INT_MAX)
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
#else
unsigned ZLIB_INTERNAL gz_intmax (void);
# define GT_OFF(x) (sizeof(int) == sizeof(int64_t) && (x) > gz_intmax())
unsigned ZLIB_INTERNAL gz_intmax OF((void));
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
#endif

View file

@ -1,3 +1,10 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* gzlib.c -- zlib functions common to reading and writing gzip files
* Copyright (C) 2004-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/limits.h"
@ -6,24 +13,22 @@
#include "libc/sysv/consts/o.h"
#include "third_party/zlib/gz/gzguts.inc"
#include "third_party/zlib/zlib.h"
// clang-format off
#include "third_party/zlib/zutil.internal.h"
/* gzlib.c -- zlib functions common to reading and writing gzip files
* Copyright (C) 2004-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#define LSEEK lseek
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/* Local functions */
static void gz_reset(gz_statep);
static gzFile gz_open(const void *, int, const char *);
/* Reset gzip file state */
static void gz_reset(state)
local void gz_reset(state)
gz_statep state;
{
state->x.have = 0; /* no output data available */
@ -32,6 +37,8 @@ static void gz_reset(state)
state->past = 0; /* have not read past end yet */
state->how = LOOK; /* look for gzip header */
}
else /* for writing ... */
state->reset = 0; /* no deflateReset pending */
state->seek = 0; /* no seek request pending */
gz_error(state, Z_OK, NULL); /* clear error */
state->x.pos = 0; /* no uncompressed data yet */
@ -39,16 +46,20 @@ static void gz_reset(state)
}
/* Open a gzip file either by name or file descriptor. */
static gzFile gz_open(path, fd, mode)
local gzFile gz_open(path, fd, mode)
const void *path;
int fd;
const char *mode;
{
gz_statep state;
size_t len;
z_size_t len;
int oflag;
#ifdef O_CLOEXEC
int cloexec = 0;
#endif
#ifdef O_EXCL
int exclusive = 0;
#endif
/* check input */
if (path == NULL)
@ -75,23 +86,29 @@ static gzFile gz_open(path, fd, mode)
case 'r':
state->mode = GZ_READ;
break;
#ifndef NO_GZCOMPRESS
case 'w':
state->mode = GZ_WRITE;
break;
case 'a':
state->mode = GZ_APPEND;
break;
#endif
case '+': /* can't read and write at the same time */
free(state);
return NULL;
case 'b': /* ignore -- will request binary anyway */
break;
#ifdef O_CLOEXEC
case 'e':
cloexec = 1;
break;
#endif
#ifdef O_EXCL
case 'x':
exclusive = 1;
break;
#endif
case 'f':
state->strategy = Z_FILTERED;
break;
@ -129,27 +146,60 @@ static gzFile gz_open(path, fd, mode)
}
/* save the path name for error messages */
len = strlen((const char *)path);
#ifdef WIDECHAR
if (fd == -2) {
len = wcstombs(NULL, path, 0);
if (len == (z_size_t)-1)
len = 0;
}
else
#endif
len = strlen((const char *)path);
state->path = (char *)malloc(len + 1);
if (state->path == NULL) {
free(state);
return NULL;
}
snprintf(state->path, len + 1, "%s", (const char *)path);
#ifdef WIDECHAR
if (fd == -2)
if (len)
wcstombs(state->path, path, len + 1);
else
*(state->path) = 0;
else
#endif
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
(void)snprintf(state->path, len + 1, "%s", (const char *)path);
#else
strcpy(state->path, path);
#endif
/* compute the flags for open() */
oflag =
#ifdef O_LARGEFILE
O_LARGEFILE |
#endif
#ifdef O_BINARY
O_BINARY |
#endif
#ifdef O_CLOEXEC
(cloexec ? O_CLOEXEC : 0) |
#endif
(state->mode == GZ_READ ?
O_RDONLY :
(O_WRONLY | O_CREAT |
#ifdef O_EXCL
(exclusive ? O_EXCL : 0) |
#endif
(state->mode == GZ_WRITE ?
O_TRUNC :
O_APPEND)));
/* open the file with the appropriate flags (or just use fd) */
state->fd = fd > -1 ? fd : (
#ifdef WIDECHAR
fd == -2 ? _wopen(path, oflag, 0666) :
#endif
open((const char *)path, oflag, 0666));
if (state->fd == -1) {
free(state->path);
@ -157,13 +207,13 @@ static gzFile gz_open(path, fd, mode)
return NULL;
}
if (state->mode == GZ_APPEND) {
lseek(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
state->mode = GZ_WRITE; /* simplify later checks */
}
/* save the current position for rewinding (only if reading) */
if (state->mode == GZ_READ) {
state->start = lseek(state->fd, 0, SEEK_CUR);
state->start = LSEEK(state->fd, 0, SEEK_CUR);
if (state->start == -1) state->start = 0;
}
@ -175,7 +225,7 @@ static gzFile gz_open(path, fd, mode)
}
/* -- see zlib.h -- */
gzFile gzopen(path, mode)
gzFile ZEXPORT gzopen(path, mode)
const char *path;
const char *mode;
{
@ -183,7 +233,7 @@ gzFile gzopen(path, mode)
}
/* -- see zlib.h -- */
gzFile gzopen64(path, mode)
gzFile ZEXPORT gzopen64(path, mode)
const char *path;
const char *mode;
{
@ -191,7 +241,7 @@ gzFile gzopen64(path, mode)
}
/* -- see zlib.h -- */
gzFile gzdopen(fd, mode)
gzFile ZEXPORT gzdopen(fd, mode)
int fd;
const char *mode;
{
@ -203,7 +253,7 @@ gzFile gzdopen(fd, mode)
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
(void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
#else
sprintf(path, "<%s:%d>", "fd", fd); /* for debugging */
sprintf(path, "<fd:%d>", fd); /* for debugging */
#endif
gz = gz_open(path, fd, mode);
free(path);
@ -211,7 +261,17 @@ gzFile gzdopen(fd, mode)
}
/* -- see zlib.h -- */
int gzbuffer(file, size)
#ifdef WIDECHAR
gzFile ZEXPORT gzopen_w(path, mode)
const wchar_t *path;
const char *mode;
{
return gz_open(path, -2, mode);
}
#endif
/* -- see zlib.h -- */
int ZEXPORT gzbuffer(file, size)
gzFile file;
unsigned size;
{
@ -238,7 +298,7 @@ int gzbuffer(file, size)
}
/* -- see zlib.h -- */
int gzrewind(file)
int ZEXPORT gzrewind(file)
gzFile file;
{
gz_statep state;
@ -254,20 +314,20 @@ int gzrewind(file)
return -1;
/* back up and start over */
if (lseek(state->fd, state->start, SEEK_SET) == -1)
if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
return -1;
gz_reset(state);
return 0;
}
/* -- see zlib.h -- */
int64_t gzseek64(file, offset, whence)
z_off64_t ZEXPORT gzseek64(file, offset, whence)
gzFile file;
int64_t offset;
z_off64_t offset;
int whence;
{
unsigned n;
int64_t ret;
z_off64_t ret;
gz_statep state;
/* get internal structure and check integrity */
@ -295,7 +355,7 @@ int64_t gzseek64(file, offset, whence)
/* if within raw area while reading, just go there */
if (state->mode == GZ_READ && state->how == COPY &&
state->x.pos + offset >= 0) {
ret = lseek(state->fd, offset - state->x.have, SEEK_CUR);
ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR);
if (ret == -1)
return -1;
state->x.have = 0;
@ -321,7 +381,7 @@ int64_t gzseek64(file, offset, whence)
/* if reading, skip what's in output buffer (one less gzgetc() check) */
if (state->mode == GZ_READ) {
n = GT_OFF(state->x.have) || (int64_t)state->x.have > offset ?
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
(unsigned)offset : state->x.have;
state->x.have -= n;
state->x.next += n;
@ -338,19 +398,19 @@ int64_t gzseek64(file, offset, whence)
}
/* -- see zlib.h -- */
int64_t gzseek(file, offset, whence)
z_off_t ZEXPORT gzseek(file, offset, whence)
gzFile file;
int64_t offset;
z_off_t offset;
int whence;
{
int64_t ret;
z_off64_t ret;
ret = gzseek64(file, (int64_t)offset, whence);
return ret == (int64_t)ret ? (int64_t)ret : -1;
ret = gzseek64(file, (z_off64_t)offset, whence);
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
}
/* -- see zlib.h -- */
int64_t gztell64(file)
z_off64_t ZEXPORT gztell64(file)
gzFile file;
{
gz_statep state;
@ -367,20 +427,20 @@ int64_t gztell64(file)
}
/* -- see zlib.h -- */
int64_t gztell(file)
z_off_t ZEXPORT gztell(file)
gzFile file;
{
int64_t ret;
z_off64_t ret;
ret = gztell64(file);
return ret == (int64_t)ret ? (int64_t)ret : -1;
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
}
/* -- see zlib.h -- */
int64_t gzoffset64(file)
z_off64_t ZEXPORT gzoffset64(file)
gzFile file;
{
int64_t offset;
z_off64_t offset;
gz_statep state;
/* get internal structure and check integrity */
@ -391,7 +451,7 @@ int64_t gzoffset64(file)
return -1;
/* compute and return effective offset in file */
offset = lseek(state->fd, 0, SEEK_CUR);
offset = LSEEK(state->fd, 0, SEEK_CUR);
if (offset == -1)
return -1;
if (state->mode == GZ_READ) /* reading */
@ -400,17 +460,17 @@ int64_t gzoffset64(file)
}
/* -- see zlib.h -- */
int64_t gzoffset(file)
z_off_t ZEXPORT gzoffset(file)
gzFile file;
{
int64_t ret;
z_off64_t ret;
ret = gzoffset64(file);
return ret == (int64_t)ret ? (int64_t)ret : -1;
return ret == (z_off_t)ret ? (z_off_t)ret : -1;
}
/* -- see zlib.h -- */
int gzeof(file)
int ZEXPORT gzeof(file)
gzFile file;
{
gz_statep state;
@ -427,7 +487,7 @@ int gzeof(file)
}
/* -- see zlib.h -- */
const char * gzerror(file, errnum)
const char * ZEXPORT gzerror(file, errnum)
gzFile file;
int *errnum;
{
@ -448,7 +508,7 @@ const char * gzerror(file, errnum)
}
/* -- see zlib.h -- */
void gzclearerr(file)
void ZEXPORT gzclearerr(file)
gzFile file;
{
gz_statep state;
@ -505,6 +565,31 @@ void ZLIB_INTERNAL gz_error(state, err, msg)
state->err = Z_MEM_ERROR;
return;
}
#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
(void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
"%s%s%s", state->path, ": ", msg);
#else
strcpy(state->msg, state->path);
strcat(state->msg, ": ");
strcat(state->msg, msg);
#endif
}
#ifndef INT_MAX
/* portably return maximum value for an int (when limits.h presumed not
available) -- we need to do this to cover cases where 2's complement not
used, since C standard permits 1's complement and sign-bit representations,
otherwise we could just use ((unsigned)-1) >> 1 */
unsigned ZLIB_INTERNAL gz_intmax()
{
unsigned p, q;
p = 1;
do {
q = p;
p <<= 1;
p++;
} while (p > q);
return q >> 1;
}
#endif

View file

@ -1,3 +1,10 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* gzread.c -- zlib functions for reading gzip files
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "libc/calls/calls.h"
#include "libc/errno.h"
#include "libc/limits.h"
@ -5,32 +12,27 @@
#include "libc/str/str.h"
#include "third_party/zlib/gz/gzguts.inc"
#include "third_party/zlib/zlib.h"
// clang-format off
/* gzread.c -- zlib functions for reading gzip files
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/* Static functions */
static int gz_load(gz_statep, unsigned char *, unsigned, unsigned *);
static int gz_avail(gz_statep);
static int gz_look(gz_statep);
static int gz_decomp(gz_statep);
static int gz_fetch(gz_statep);
static int gz_skip(gz_statep, int64_t);
static size_t gz_read(gz_statep, voidp, size_t);
/* Local functions */
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
local int gz_avail OF((gz_statep));
local int gz_look OF((gz_statep));
local int gz_decomp OF((gz_statep));
local int gz_fetch OF((gz_statep));
local int gz_skip OF((gz_statep, z_off64_t));
local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
state->fd, and update state->eof, state->err, and state->msg as appropriate.
This function needs to loop on read(), since read() is not guaranteed to
read the number of bytes requested, depending on the type of descriptor. */
static int gz_load(state, buf, len, have)
local int gz_load(state, buf, len, have)
gz_statep state;
unsigned char *buf;
unsigned len;
@ -65,7 +67,7 @@ static int gz_load(state, buf, len, have)
If strm->avail_in != 0, then the current data is moved to the beginning of
the input buffer, and then the remainder of the buffer is loaded with the
available data from the input file. */
static int gz_avail(state)
local int gz_avail(state)
gz_statep state;
{
unsigned got;
@ -100,7 +102,7 @@ static int gz_avail(state)
case, all further file reads will be directly to either the output buffer or
a user buffer. If decompressing, the inflate state will be initialized.
gz_look() will return 0 on success or -1 on failure. */
static int gz_look(state)
local int gz_look(state)
gz_statep state;
{
z_streamp strm = &(state->strm);
@ -184,7 +186,7 @@ static int gz_look(state)
data. If the gzip stream completes, state->how is reset to LOOK to look for
the next gzip stream or raw data, once state->x.have is depleted. Returns 0
on success, -1 on failure. */
static int gz_decomp(state)
local int gz_decomp(state)
gz_statep state;
{
int ret = Z_OK;
@ -238,7 +240,7 @@ static int gz_decomp(state)
looked for to determine whether to copy or decompress. Returns -1 on error,
otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
end of the input file has been reached and all data has been processed. */
static int gz_fetch(state)
local int gz_fetch(state)
gz_statep state;
{
z_streamp strm = &(state->strm);
@ -268,9 +270,9 @@ static int gz_fetch(state)
}
/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
static int gz_skip(state, len)
local int gz_skip(state, len)
gz_statep state;
int64_t len;
z_off64_t len;
{
unsigned n;
@ -278,7 +280,7 @@ static int gz_skip(state, len)
while (len)
/* skip over whatever is in output buffer */
if (state->x.have) {
n = GT_OFF(state->x.have) || (int64_t)state->x.have > len ?
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
(unsigned)len : state->x.have;
state->x.have -= n;
state->x.next += n;
@ -303,12 +305,12 @@ static int gz_skip(state, len)
input. Return the number of bytes read. If zero is returned, either the
end of file was reached, or there was an error. state->err must be
consulted in that case to determine which. */
static size_t gz_read(state, buf, len)
local z_size_t gz_read(state, buf, len)
gz_statep state;
voidp buf;
size_t len;
z_size_t len;
{
size_t got;
z_size_t got;
unsigned n;
/* if len is zero, avoid unnecessary operations */
@ -326,9 +328,9 @@ static size_t gz_read(state, buf, len)
got = 0;
do {
/* set n to the maximum amount of len that fits in an unsigned int */
n = -1;
n = (unsigned)-1;
if (n > len)
n = len;
n = (unsigned)len;
/* first just try copying data from the output buffer */
if (state->x.have) {
@ -384,7 +386,7 @@ static size_t gz_read(state, buf, len)
}
/* -- see zlib.h -- */
int gzread(file, buf, len)
int ZEXPORT gzread(file, buf, len)
gzFile file;
voidp buf;
unsigned len;
@ -409,7 +411,7 @@ int gzread(file, buf, len)
}
/* read len or fewer bytes to buf */
len = gz_read(state, buf, len);
len = (unsigned)gz_read(state, buf, len);
/* check for an error */
if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
@ -420,13 +422,13 @@ int gzread(file, buf, len)
}
/* -- see zlib.h -- */
size_t gzfread(buf, size, nitems, file)
z_size_t ZEXPORT gzfread(buf, size, nitems, file)
voidp buf;
size_t size;
size_t nitems;
z_size_t size;
z_size_t nitems;
gzFile file;
{
size_t len;
z_size_t len;
gz_statep state;
/* get internal structure */
@ -460,10 +462,9 @@ size_t gzfread(buf, size, nitems, file)
# endif
#endif
int gzgetc(file)
int ZEXPORT gzgetc(file)
gzFile file;
{
int ret;
unsigned char buf[1];
gz_statep state;
@ -485,18 +486,17 @@ int gzgetc(file)
}
/* nothing there -- try gz_read() */
ret = gz_read(state, buf, 1);
return ret < 1 ? -1 : buf[0];
return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
}
int gzgetc_(file)
int ZEXPORT gzgetc_(file)
gzFile file;
{
return gzgetc(file);
}
/* -- see zlib.h -- */
int gzungetc(c, file)
int ZEXPORT gzungetc(c, file)
int c;
gzFile file;
{
@ -556,7 +556,7 @@ int gzungetc(c, file)
}
/* -- see zlib.h -- */
char * gzgets(file, buf, len)
char * ZEXPORT gzgets(file, buf, len)
gzFile file;
char *buf;
int len;
@ -620,7 +620,7 @@ char * gzgets(file, buf, len)
}
/* -- see zlib.h -- */
int gzdirect(file)
int ZEXPORT gzdirect(file)
gzFile file;
{
gz_statep state;
@ -640,7 +640,7 @@ int gzdirect(file)
}
/* -- see zlib.h -- */
int gzclose_r(file)
int ZEXPORT gzclose_r(file)
gzFile file;
{
int ret, err;

View file

@ -1,29 +1,31 @@
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/mem/mem.h"
#include "third_party/zlib/gz/gzguts.inc"
// clang-format off
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* gzwrite.c -- zlib functions for writing gzip files
* Copyright (C) 2004-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/mem/mem.h"
#include "third_party/zlib/gz/gzguts.inc"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/* Static functions */
static int gz_init(gz_statep);
static int gz_comp(gz_statep, int);
static int gz_zero(gz_statep, int64_t);
static size_t gz_write(gz_statep, voidpc, size_t);
/* Local functions */
local int gz_init OF((gz_statep));
local int gz_comp OF((gz_statep, int));
local int gz_zero OF((gz_statep, z_off64_t));
local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
/* Initialize state for writing a gzip file. Mark initialization by setting
state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
success. */
static int gz_init(state)
local int gz_init(state)
gz_statep state;
{
int ret;
@ -79,7 +81,7 @@ static int gz_init(state)
deflate() flush value. If flush is Z_FINISH, then the deflate() state is
reset to start a new gzip stream. If gz->direct is true, then simply write
to the output file without compressing, and ignore flush. */
static int gz_comp(state, flush)
local int gz_comp(state, flush)
gz_statep state;
int flush;
{
@ -106,6 +108,15 @@ static int gz_comp(state, flush)
return 0;
}
/* check for a pending reset */
if (state->reset) {
/* don't start a new gzip member unless there is data to write */
if (strm->avail_in == 0)
return 0;
deflateReset(strm);
state->reset = 0;
}
/* run deflate() on provided input until it produces no more output */
ret = Z_OK;
do {
@ -143,7 +154,7 @@ static int gz_comp(state, flush)
/* if that completed a deflate stream, allow another to start */
if (flush == Z_FINISH)
deflateReset(strm);
state->reset = 1;
/* all done, no errors */
return 0;
@ -151,9 +162,9 @@ static int gz_comp(state, flush)
/* Compress len zeros to output. Return -1 on a write error or memory
allocation failure by gz_comp(), or 0 on success. */
static int gz_zero(state, len)
local int gz_zero(state, len)
gz_statep state;
int64_t len;
z_off64_t len;
{
int first;
unsigned n;
@ -166,7 +177,7 @@ static int gz_zero(state, len)
/* compress len zeros (len guaranteed > 0) */
first = 1;
while (len) {
n = GT_OFF(state->size) || (int64_t)state->size > len ?
n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
(unsigned)len : state->size;
if (first) {
memset(state->in, 0, n);
@ -184,12 +195,12 @@ static int gz_zero(state, len)
/* Write len bytes from buf to file. Return the number of bytes written. If
the returned value is less than len, then there was an error. */
static size_t gz_write(state, buf, len)
local z_size_t gz_write(state, buf, len)
gz_statep state;
voidpc buf;
size_t len;
z_size_t len;
{
size_t put = len;
z_size_t put = len;
/* if len is zero, avoid unnecessary operations */
if (len == 0)
@ -218,7 +229,7 @@ static size_t gz_write(state, buf, len)
state->in);
copy = state->size - have;
if (copy > len)
copy = len;
copy = (unsigned)len;
memcpy(state->in + have, buf, copy);
state->strm.avail_in += copy;
state->x.pos += copy;
@ -234,11 +245,11 @@ static size_t gz_write(state, buf, len)
return 0;
/* directly compress user buffer to file */
state->strm.next_in = (const Bytef *)buf;
state->strm.next_in = (Bytef *)buf;
do {
unsigned n = (unsigned)-1;
if (n > len)
n = len;
n = (unsigned)len;
state->strm.avail_in = n;
state->x.pos += n;
if (gz_comp(state, Z_NO_FLUSH) == -1)
@ -252,7 +263,7 @@ static size_t gz_write(state, buf, len)
}
/* -- see zlib.h -- */
int gzwrite(file, buf, len)
int ZEXPORT gzwrite(file, buf, len)
gzFile file;
voidpc buf;
unsigned len;
@ -280,13 +291,13 @@ int gzwrite(file, buf, len)
}
/* -- see zlib.h -- */
size_t gzfwrite(buf, size, nitems, file)
z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
voidpc buf;
size_t size;
size_t nitems;
z_size_t size;
z_size_t nitems;
gzFile file;
{
size_t len;
z_size_t len;
gz_statep state;
/* get internal structure */
@ -310,7 +321,7 @@ size_t gzfwrite(buf, size, nitems, file)
}
/* -- see zlib.h -- */
int gzputc(file, c)
int ZEXPORT gzputc(file, c)
gzFile file;
int c;
{
@ -358,12 +369,11 @@ int gzputc(file, c)
}
/* -- see zlib.h -- */
int gzputs(file, str)
int ZEXPORT gzputs(file, s)
gzFile file;
const char *str;
const char *s;
{
int ret;
size_t len;
z_size_t len, put;
gz_statep state;
/* get internal structure */
@ -376,13 +386,19 @@ int gzputs(file, str)
return -1;
/* write string */
len = strlen(str);
ret = gz_write(state, str, len);
return ret == 0 && len != 0 ? -1 : ret;
len = strlen(s);
if ((int)len < 0 || (unsigned)len != len) {
gz_error(state, Z_STREAM_ERROR, "string length does not fit in int");
return -1;
}
put = gz_write(state, s, len);
return put < len ? -1 : (int)len;
}
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
/* -- see zlib.h -- */
int gzvprintf(gzFile file, const char *format, va_list va)
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
{
int len;
unsigned left;
@ -418,7 +434,22 @@ int gzvprintf(gzFile file, const char *format, va_list va)
strm->next_in = state->in;
next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
next[state->size - 1] = 0;
len = (vsnprintf)(next, state->size, format, va);
#ifdef NO_vsnprintf
# ifdef HAS_vsprintf_void
(void)vsprintf(next, format, va);
for (len = 0; len < state->size; len++)
if (next[len] == 0) break;
# else
len = vsprintf(next, format, va);
# endif
#else
# ifdef HAS_vsnprintf_void
(void)vsnprintf(next, state->size, format, va);
len = strlen(next);
# else
len = vsnprintf(next, state->size, format, va);
# endif
#endif
/* check that printf() results fit in buffer */
if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
@ -432,14 +463,14 @@ int gzvprintf(gzFile file, const char *format, va_list va)
strm->avail_in = state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->err;
memcpy(state->in, state->in + state->size, left);
memmove(state->in, state->in + state->size, left);
strm->next_in = state->in;
strm->avail_in = left;
}
return len;
}
int gzprintf(gzFile file, const char *format, ...)
int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
{
va_list va;
int ret;
@ -450,8 +481,98 @@ int gzprintf(gzFile file, const char *format, ...)
return ret;
}
#else /* !STDC && !Z_HAVE_STDARG_H */
/* -- see zlib.h -- */
int gzflush(file, flush)
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
gzFile file;
const char *format;
int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
{
unsigned len, left;
char *next;
gz_statep state;
z_streamp strm;
/* get internal structure */
if (file == NULL)
return Z_STREAM_ERROR;
state = (gz_statep)file;
strm = &(state->strm);
/* check that can really pass pointer in ints */
if (sizeof(int) != sizeof(void *))
return Z_STREAM_ERROR;
/* check that we're writing and that there's no error */
if (state->mode != GZ_WRITE || state->err != Z_OK)
return Z_STREAM_ERROR;
/* make sure we have some buffer space */
if (state->size == 0 && gz_init(state) == -1)
return state->error;
/* check for seek request */
if (state->seek) {
state->seek = 0;
if (gz_zero(state, state->skip) == -1)
return state->error;
}
/* do the printf() into the input buffer, put length in len -- the input
buffer is double-sized just for this function, so there is guaranteed to
be state->size bytes available after the current contents */
if (strm->avail_in == 0)
strm->next_in = state->in;
next = (char *)(strm->next_in + strm->avail_in);
next[state->size - 1] = 0;
#ifdef NO_snprintf
# ifdef HAS_sprintf_void
sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
a13, a14, a15, a16, a17, a18, a19, a20);
for (len = 0; len < size; len++)
if (next[len] == 0)
break;
# else
len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif
#else
# ifdef HAS_snprintf_void
snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
len = strlen(next);
# else
len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
# endif
#endif
/* check that printf() results fit in buffer */
if (len == 0 || len >= state->size || next[state->size - 1] != 0)
return 0;
/* update buffer and position, compress first half if past that */
strm->avail_in += len;
state->x.pos += len;
if (strm->avail_in >= state->size) {
left = strm->avail_in - state->size;
strm->avail_in = state->size;
if (gz_comp(state, Z_NO_FLUSH) == -1)
return state->err;
memmove(state->in, state->in + state->size, left);
strm->next_in = state->in;
strm->avail_in = left;
}
return (int)len;
}
#endif
/* -- see zlib.h -- */
int ZEXPORT gzflush(file, flush)
gzFile file;
int flush;
{
@ -483,7 +604,7 @@ int gzflush(file, flush)
}
/* -- see zlib.h -- */
int gzsetparams(file, level, strategy)
int ZEXPORT gzsetparams(file, level, strategy)
gzFile file;
int level;
int strategy;
@ -525,7 +646,7 @@ int gzsetparams(file, level, strategy)
}
/* -- see zlib.h -- */
int gzclose_w(file)
int ZEXPORT gzclose_w(file)
gzFile file;
{
int ret = Z_OK;

View file

@ -1,3 +1,6 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* infback.c -- inflate using a call-back interface
* Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
@ -8,6 +11,11 @@
#include "third_party/zlib/internal.h"
#include "third_party/zlib/macros.internal.h"
#include "third_party/zlib/zutil.internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/*

View file

@ -1,7 +1,15 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* inffast.c -- fast decoding
* Copyright (C) 1995-2017 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
#include "third_party/zlib/zutil.internal.h"

View file

@ -1,3 +1,6 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* inflate.c -- zlib decompression
* Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
@ -6,6 +9,11 @@
#include "third_party/zlib/inflate.internal.h"
#include "third_party/zlib/inftrees.internal.h"
#include "third_party/zlib/internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/*

View file

@ -1,8 +1,16 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* inftrees.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2022 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "third_party/zlib/inftrees.internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
#define MAXBITS 15

View file

@ -1,12 +1,41 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Copyright (C) 2002-2013 Mark Adler, all rights reserved
version 2.3, 21 Jan 2013
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Mark Adler madler@alumni.caltech.edu
*/
#include "libc/runtime/runtime.h"
#include "third_party/zlib/puff.h"
// clang-format off
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
puff (zlib License)\\n\
Copyright 2002-203 Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// Origin: git@github.com:madler/zlib.git
// Commit: 03614c56ad299f9b238c75aa1e66f0c08fc4fc8b
// Author: Mark Adler <madler@alumni.caltech.edu>
// Date: Sun Oct 30 08:36:13 2016 -0700
/*
* puff.c
* Copyright (C) 2002-2013 Mark Adler
@ -88,36 +117,34 @@ asm(".include \"libc/disclaimer.inc\"");
* 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks
*/
#ifndef NIL
# define NIL ((unsigned char *)0) /* for no output option */
#endif
#define local static /* for local function definitions */
/*
* Maximums for allocations and loops. It is not useful to change these --
* they are fixed by the deflate format.
*/
#define MAXBITS 15 /* maximum bits in a code */
#define MAXLCODES 286 /* maximum number of literal/length codes */
#define MAXDCODES 30 /* maximum number of distance codes */
#define MAXCODES (MAXLCODES + MAXDCODES) /* maximum codes lengths to read */
#define FIXLCODES 288 /* number of fixed literal/length codes */
#define MAXBITS 15 /* maximum bits in a code */
#define MAXLCODES 286 /* maximum number of literal/length codes */
#define MAXDCODES 30 /* maximum number of distance codes */
#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */
#define FIXLCODES 288 /* number of fixed literal/length codes */
/* input and output state */
struct state {
/* output state */
unsigned char *out; /* output buffer */
unsigned long outlen; /* available space at out */
unsigned long outcnt; /* bytes written to out so far */
/* output state */
unsigned char *out; /* output buffer */
unsigned long outlen; /* available space at out */
unsigned long outcnt; /* bytes written to out so far */
/* input state */
const unsigned char *in; /* input buffer */
unsigned long inlen; /* available input at in */
unsigned long incnt; /* bytes read so far */
int bitbuf; /* bit buffer */
int bitcnt; /* number of bits in bit buffer */
/* input state */
const unsigned char *in; /* input buffer */
unsigned long inlen; /* available input at in */
unsigned long incnt; /* bytes read so far */
int bitbuf; /* bit buffer */
int bitcnt; /* number of bits in bit buffer */
/* input limit error return state for bits() and decode() */
jmp_buf env;
/* input limit error return state for bits() and decode() */
jmp_buf env;
};
/*
@ -131,23 +158,25 @@ struct state {
* buffer, using shift right, and new bytes are appended to the top of the
* bit buffer, using shift left.
*/
static noinstrument int bits(struct state *s, int need) {
long val; /* bit accumulator (can use up to 20 bits) */
local int bits(struct state *s, int need)
{
long val; /* bit accumulator (can use up to 20 bits) */
/* load at least need bits into val */
val = s->bitbuf;
while (s->bitcnt < need) {
if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
s->bitcnt += 8;
}
/* load at least need bits into val */
val = s->bitbuf;
while (s->bitcnt < need) {
if (s->incnt == s->inlen)
longjmp(s->env, 1); /* out of input */
val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
s->bitcnt += 8;
}
/* drop need bits and update buffer, always zero to seven bits left */
s->bitbuf = (int)(val >> need);
s->bitcnt -= need;
/* drop need bits and update buffer, always zero to seven bits left */
s->bitbuf = (int)(val >> need);
s->bitcnt -= need;
/* return need bits, zeroing the bits above that */
return (int)(val & ((1L << need) - 1));
/* return need bits, zeroing the bits above that */
return (int)(val & ((1L << need) - 1));
}
/*
@ -167,33 +196,39 @@ static noinstrument int bits(struct state *s, int need) {
* - A stored block can have zero length. This is sometimes used to byte-align
* subsets of the compressed data for random access or partial recovery.
*/
static int stored(struct state *s) {
unsigned len; /* length of stored block */
local int stored(struct state *s)
{
unsigned len; /* length of stored block */
/* discard leftover bits from current byte (assumes s->bitcnt < 8) */
s->bitbuf = 0;
s->bitcnt = 0;
/* discard leftover bits from current byte (assumes s->bitcnt < 8) */
s->bitbuf = 0;
s->bitcnt = 0;
/* get length and check against its one's complement */
if (s->incnt + 4 > s->inlen) return 2; /* not enough input */
len = s->in[s->incnt++];
len |= s->in[s->incnt++] << 8;
if (s->in[s->incnt++] != (~len & 0xff) ||
s->in[s->incnt++] != ((~len >> 8) & 0xff))
return -2; /* didn't match complement! */
/* get length and check against its one's complement */
if (s->incnt + 4 > s->inlen)
return 2; /* not enough input */
len = s->in[s->incnt++];
len |= s->in[s->incnt++] << 8;
if (s->in[s->incnt++] != (~len & 0xff) ||
s->in[s->incnt++] != ((~len >> 8) & 0xff))
return -2; /* didn't match complement! */
/* copy len bytes from in to out */
if (s->incnt + len > s->inlen) return 2; /* not enough input */
if (s->out != NIL) {
if (s->outcnt + len > s->outlen) return 1; /* not enough output space */
while (len--) s->out[s->outcnt++] = s->in[s->incnt++];
} else { /* just scanning */
s->outcnt += len;
s->incnt += len;
}
/* copy len bytes from in to out */
if (s->incnt + len > s->inlen)
return 2; /* not enough input */
if (s->out != NIL) {
if (s->outcnt + len > s->outlen)
return 1; /* not enough output space */
while (len--)
s->out[s->outcnt++] = s->in[s->incnt++];
}
else { /* just scanning */
s->outcnt += len;
s->incnt += len;
}
/* done with a valid stored block */
return 0;
/* done with a valid stored block */
return 0;
}
/*
@ -204,8 +239,8 @@ static int stored(struct state *s) {
* seen in the function decode() below.
*/
struct huffman {
short *count; /* number of symbols of each length */
short *symbol; /* canonically ordered symbols */
short *count; /* number of symbols of each length */
short *symbol; /* canonically ordered symbols */
};
/*
@ -232,25 +267,26 @@ struct huffman {
* in the deflate format. See the format notes for fixed() and dynamic().
*/
#ifdef SLOW
static int decode(struct state *s, const struct huffman *h) {
int len; /* current number of bits in code */
int code; /* len bits being decoded */
int first; /* first code of length len */
int count; /* number of codes of length len */
int index; /* index of first code of length len in symbol table */
local int decode(struct state *s, const struct huffman *h)
{
int len; /* current number of bits in code */
int code; /* len bits being decoded */
int first; /* first code of length len */
int count; /* number of codes of length len */
int index; /* index of first code of length len in symbol table */
code = first = index = 0;
for (len = 1; len <= MAXBITS; len++) {
code |= bits(s, 1); /* get next bit */
count = h->count[len];
if (code - count < first) /* if length len, return symbol */
return h->symbol[index + (code - first)];
index += count; /* else update for next length */
first += count;
first <<= 1;
code <<= 1;
}
return -10; /* ran out of codes */
code = first = index = 0;
for (len = 1; len <= MAXBITS; len++) {
code |= bits(s, 1); /* get next bit */
count = h->count[len];
if (code - count < first) /* if length len, return symbol */
return h->symbol[index + (code - first)];
index += count; /* else update for next length */
first += count;
first <<= 1;
code <<= 1;
}
return -10; /* ran out of codes */
}
/*
@ -259,44 +295,48 @@ static int decode(struct state *s, const struct huffman *h) {
* a few percent larger.
*/
#else /* !SLOW */
static int decode(struct state *s, const struct huffman *h) {
int len; /* current number of bits in code */
int code; /* len bits being decoded */
int first; /* first code of length len */
int count; /* number of codes of length len */
int index; /* index of first code of length len in symbol table */
int bitbuf; /* bits from stream */
int left; /* bits left in next or left to process */
short *next; /* next number of codes */
local int decode(struct state *s, const struct huffman *h)
{
int len; /* current number of bits in code */
int code; /* len bits being decoded */
int first; /* first code of length len */
int count; /* number of codes of length len */
int index; /* index of first code of length len in symbol table */
int bitbuf; /* bits from stream */
int left; /* bits left in next or left to process */
short *next; /* next number of codes */
bitbuf = s->bitbuf;
left = s->bitcnt;
code = first = index = 0;
len = 1;
next = h->count + 1;
while (1) {
while (left--) {
code |= bitbuf & 1;
bitbuf >>= 1;
count = *next++;
if (code - count < first) { /* if length len, return symbol */
s->bitbuf = bitbuf;
s->bitcnt = (s->bitcnt - len) & 7;
return h->symbol[index + (code - first)];
}
index += count; /* else update for next length */
first += count;
first <<= 1;
code <<= 1;
len++;
bitbuf = s->bitbuf;
left = s->bitcnt;
code = first = index = 0;
len = 1;
next = h->count + 1;
while (1) {
while (left--) {
code |= bitbuf & 1;
bitbuf >>= 1;
count = *next++;
if (code - count < first) { /* if length len, return symbol */
s->bitbuf = bitbuf;
s->bitcnt = (s->bitcnt - len) & 7;
return h->symbol[index + (code - first)];
}
index += count; /* else update for next length */
first += count;
first <<= 1;
code <<= 1;
len++;
}
left = (MAXBITS+1) - len;
if (left == 0)
break;
if (s->incnt == s->inlen)
longjmp(s->env, 1); /* out of input */
bitbuf = s->in[s->incnt++];
if (left > 8)
left = 8;
}
left = (MAXBITS + 1) - len;
if (left == 0) break;
if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
bitbuf = s->in[s->incnt++];
if (left > 8) left = 8;
}
return -10; /* ran out of codes */
return -10; /* ran out of codes */
}
#endif /* SLOW */
@ -332,40 +372,45 @@ static int decode(struct state *s, const struct huffman *h) {
* - Within a given code length, the symbols are kept in ascending order for
* the code bits definition.
*/
static int construct(struct huffman *h, const short *length, int n) {
int symbol; /* current symbol when stepping through length[] */
int len; /* current length when stepping through h->count[] */
int left; /* number of possible codes left of current length */
short offs[MAXBITS + 1]; /* offsets in symbol table for each length */
local int construct(struct huffman *h, const short *length, int n)
{
int symbol; /* current symbol when stepping through length[] */
int len; /* current length when stepping through h->count[] */
int left; /* number of possible codes left of current length */
short offs[MAXBITS+1]; /* offsets in symbol table for each length */
/* count number of codes of each length */
for (len = 0; len <= MAXBITS; len++) h->count[len] = 0;
for (symbol = 0; symbol < n; symbol++)
(h->count[length[symbol]])++; /* assumes lengths are within bounds */
if (h->count[0] == n) /* no codes! */
return 0; /* complete, but decode() will fail */
/* count number of codes of each length */
for (len = 0; len <= MAXBITS; len++)
h->count[len] = 0;
for (symbol = 0; symbol < n; symbol++)
(h->count[length[symbol]])++; /* assumes lengths are within bounds */
if (h->count[0] == n) /* no codes! */
return 0; /* complete, but decode() will fail */
/* check for an over-subscribed or incomplete set of lengths */
left = 1; /* one possible code of zero length */
for (len = 1; len <= MAXBITS; len++) {
left <<= 1; /* one more bit, double codes left */
left -= h->count[len]; /* deduct count from possible codes */
if (left < 0) return left; /* over-subscribed--return negative */
} /* left > 0 means incomplete */
/* check for an over-subscribed or incomplete set of lengths */
left = 1; /* one possible code of zero length */
for (len = 1; len <= MAXBITS; len++) {
left <<= 1; /* one more bit, double codes left */
left -= h->count[len]; /* deduct count from possible codes */
if (left < 0)
return left; /* over-subscribed--return negative */
} /* left > 0 means incomplete */
/* generate offsets into symbol table for each length for sorting */
offs[1] = 0;
for (len = 1; len < MAXBITS; len++) offs[len + 1] = offs[len] + h->count[len];
/* generate offsets into symbol table for each length for sorting */
offs[1] = 0;
for (len = 1; len < MAXBITS; len++)
offs[len + 1] = offs[len] + h->count[len];
/*
* put symbols in table sorted by length, by symbol order within each
* length
*/
for (symbol = 0; symbol < n; symbol++)
if (length[symbol] != 0) h->symbol[offs[length[symbol]]++] = symbol;
/*
* put symbols in table sorted by length, by symbol order within each
* length
*/
for (symbol = 0; symbol < n; symbol++)
if (length[symbol] != 0)
h->symbol[offs[length[symbol]]++] = symbol;
/* return zero for complete set, positive for incomplete set */
return left;
/* return zero for complete set, positive for incomplete set */
return left;
}
/*
@ -423,71 +468,80 @@ static int construct(struct huffman *h, const short *length, int n) {
* since though their behavior -is- defined for overlapping arrays, it is
* defined to do the wrong thing in this case.
*/
static int codes(struct state *s, const struct huffman *lencode,
const struct huffman *distcode) {
int symbol; /* decoded symbol */
int len; /* length for copy */
unsigned dist; /* distance for copy */
static const short lens[29] = {/* Size base for length codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
67, 83, 99, 115, 131, 163, 195, 227, 258};
static const short lext[29] = {/* Extra bits for length codes 257..285 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
static const short dists[30] = {
/* Offset base for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
static const short dext[30] = {/* Extra bits for distance codes 0..29 */
0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
local int codes(struct state *s,
const struct huffman *lencode,
const struct huffman *distcode)
{
int symbol; /* decoded symbol */
int len; /* length for copy */
unsigned dist; /* distance for copy */
static const short lens[29] = { /* Size base for length codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
static const short lext[29] = { /* Extra bits for length codes 257..285 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
static const short dists[30] = { /* Offset base for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577};
static const short dext[30] = { /* Extra bits for distance codes 0..29 */
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13};
/* decode literals and length/distance pairs */
do {
symbol = decode(s, lencode);
if (symbol < 0) return symbol; /* invalid symbol */
if (symbol < 256) { /* literal: symbol is the byte */
/* write out the literal */
if (s->out != NIL) {
if (s->outcnt == s->outlen) return 1;
s->out[s->outcnt] = symbol;
}
s->outcnt++;
} else if (symbol > 256) { /* length */
/* get and compute length */
symbol -= 257;
if (symbol >= 29) return -10; /* invalid fixed code */
len = lens[symbol] + bits(s, lext[symbol]);
/* get and check distance */
symbol = decode(s, distcode);
if (symbol < 0) return symbol; /* invalid symbol */
dist = dists[symbol] + bits(s, dext[symbol]);
#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
if (dist > s->outcnt) return -11; /* distance too far back */
#endif
/* copy length bytes from distance bytes back */
if (s->out != NIL) {
if (s->outcnt + len > s->outlen) return 1;
while (len--) {
s->out[s->outcnt] =
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
dist > s->outcnt ? 0 :
#endif
s->out[s->outcnt - dist];
s->outcnt++;
/* decode literals and length/distance pairs */
do {
symbol = decode(s, lencode);
if (symbol < 0)
return symbol; /* invalid symbol */
if (symbol < 256) { /* literal: symbol is the byte */
/* write out the literal */
if (s->out != NIL) {
if (s->outcnt == s->outlen)
return 1;
s->out[s->outcnt] = symbol;
}
s->outcnt++;
}
} else
s->outcnt += len;
}
} while (symbol != 256); /* end of block symbol */
else if (symbol > 256) { /* length */
/* get and compute length */
symbol -= 257;
if (symbol >= 29)
return -10; /* invalid fixed code */
len = lens[symbol] + bits(s, lext[symbol]);
/* done with a valid fixed or dynamic block */
return 0;
/* get and check distance */
symbol = decode(s, distcode);
if (symbol < 0)
return symbol; /* invalid symbol */
dist = dists[symbol] + bits(s, dext[symbol]);
#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
if (dist > s->outcnt)
return -11; /* distance too far back */
#endif
/* copy length bytes from distance bytes back */
if (s->out != NIL) {
if (s->outcnt + len > s->outlen)
return 1;
while (len--) {
s->out[s->outcnt] =
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
dist > s->outcnt ?
0 :
#endif
s->out[s->outcnt - dist];
s->outcnt++;
}
}
else
s->outcnt += len;
}
} while (symbol != 256); /* end of block symbol */
/* done with a valid fixed or dynamic block */
return 0;
}
/*
@ -514,40 +568,46 @@ static int codes(struct state *s, const struct huffman *lencode,
* length, this can be implemented as an incomplete code. Then the invalid
* codes are detected while decoding.
*/
static int fixed(struct state *s) {
static int virgin = 1;
static short lencnt[MAXBITS + 1], lensym[FIXLCODES];
static short distcnt[MAXBITS + 1], distsym[MAXDCODES];
static struct huffman lencode, distcode;
local int fixed(struct state *s)
{
static int virgin = 1;
static short lencnt[MAXBITS+1], lensym[FIXLCODES];
static short distcnt[MAXBITS+1], distsym[MAXDCODES];
static struct huffman lencode, distcode;
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
int symbol;
short lengths[FIXLCODES];
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
int symbol;
short lengths[FIXLCODES];
/* construct lencode and distcode */
lencode.count = lencnt;
lencode.symbol = lensym;
distcode.count = distcnt;
distcode.symbol = distsym;
/* construct lencode and distcode */
lencode.count = lencnt;
lencode.symbol = lensym;
distcode.count = distcnt;
distcode.symbol = distsym;
/* literal/length table */
for (symbol = 0; symbol < 144; symbol++) lengths[symbol] = 8;
for (; symbol < 256; symbol++) lengths[symbol] = 9;
for (; symbol < 280; symbol++) lengths[symbol] = 7;
for (; symbol < FIXLCODES; symbol++) lengths[symbol] = 8;
construct(&lencode, lengths, FIXLCODES);
/* literal/length table */
for (symbol = 0; symbol < 144; symbol++)
lengths[symbol] = 8;
for (; symbol < 256; symbol++)
lengths[symbol] = 9;
for (; symbol < 280; symbol++)
lengths[symbol] = 7;
for (; symbol < FIXLCODES; symbol++)
lengths[symbol] = 8;
construct(&lencode, lengths, FIXLCODES);
/* distance table */
for (symbol = 0; symbol < MAXDCODES; symbol++) lengths[symbol] = 5;
construct(&distcode, lengths, MAXDCODES);
/* distance table */
for (symbol = 0; symbol < MAXDCODES; symbol++)
lengths[symbol] = 5;
construct(&distcode, lengths, MAXDCODES);
/* do this just once */
virgin = 0;
}
/* do this just once */
virgin = 0;
}
/* decode data until end-of-block code */
return codes(s, &lencode, &distcode);
/* decode data until end-of-block code */
return codes(s, &lencode, &distcode);
}
/*
@ -637,79 +697,88 @@ static int fixed(struct state *s) {
* - For reference, a "typical" size for the code description in a dynamic
* block is around 80 bytes.
*/
static int dynamic(struct state *s) {
int nlen, ndist, ncode; /* number of lengths in descriptor */
int index; /* index of lengths[] */
int err; /* construct() return value */
short lengths[MAXCODES]; /* descriptor code lengths */
short lencnt[MAXBITS + 1], lensym[MAXLCODES]; /* lencode memory */
short distcnt[MAXBITS + 1], distsym[MAXDCODES]; /* distcode memory */
struct huffman lencode, distcode; /* length and distance codes */
static const short order[19] = /* permutation of code length codes */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
local int dynamic(struct state *s)
{
int nlen, ndist, ncode; /* number of lengths in descriptor */
int index; /* index of lengths[] */
int err; /* construct() return value */
short lengths[MAXCODES]; /* descriptor code lengths */
short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
struct huffman lencode, distcode; /* length and distance codes */
static const short order[19] = /* permutation of code length codes */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/* construct lencode and distcode */
lencode.count = lencnt;
lencode.symbol = lensym;
distcode.count = distcnt;
distcode.symbol = distsym;
/* construct lencode and distcode */
lencode.count = lencnt;
lencode.symbol = lensym;
distcode.count = distcnt;
distcode.symbol = distsym;
/* get number of lengths in each table, check lengths */
nlen = bits(s, 5) + 257;
ndist = bits(s, 5) + 1;
ncode = bits(s, 4) + 4;
if (nlen > MAXLCODES || ndist > MAXDCODES) return -3; /* bad counts */
/* get number of lengths in each table, check lengths */
nlen = bits(s, 5) + 257;
ndist = bits(s, 5) + 1;
ncode = bits(s, 4) + 4;
if (nlen > MAXLCODES || ndist > MAXDCODES)
return -3; /* bad counts */
/* read code length code lengths (really), missing lengths are zero */
for (index = 0; index < ncode; index++) lengths[order[index]] = bits(s, 3);
for (; index < 19; index++) lengths[order[index]] = 0;
/* read code length code lengths (really), missing lengths are zero */
for (index = 0; index < ncode; index++)
lengths[order[index]] = bits(s, 3);
for (; index < 19; index++)
lengths[order[index]] = 0;
/* build huffman table for code lengths codes (use lencode temporarily) */
err = construct(&lencode, lengths, 19);
if (err != 0) /* require complete code set here */
return -4;
/* build huffman table for code lengths codes (use lencode temporarily) */
err = construct(&lencode, lengths, 19);
if (err != 0) /* require complete code set here */
return -4;
/* read length/literal and distance code length tables */
index = 0;
while (index < nlen + ndist) {
int symbol; /* decoded value */
int len; /* last length to repeat */
/* read length/literal and distance code length tables */
index = 0;
while (index < nlen + ndist) {
int symbol; /* decoded value */
int len; /* last length to repeat */
symbol = decode(s, &lencode);
if (symbol < 0) return symbol; /* invalid symbol */
if (symbol < 16) /* length in 0..15 */
lengths[index++] = symbol;
else { /* repeat instruction */
len = 0; /* assume repeating zeros */
if (symbol == 16) { /* repeat last length 3..6 times */
if (index == 0) return -5; /* no last length! */
len = lengths[index - 1]; /* last length */
symbol = 3 + bits(s, 2);
} else if (symbol == 17) /* repeat zero 3..10 times */
symbol = 3 + bits(s, 3);
else /* == 18, repeat zero 11..138 times */
symbol = 11 + bits(s, 7);
if (index + symbol > nlen + ndist) return -6; /* too many lengths! */
while (symbol--) /* repeat last or zero symbol times */
lengths[index++] = len;
symbol = decode(s, &lencode);
if (symbol < 0)
return symbol; /* invalid symbol */
if (symbol < 16) /* length in 0..15 */
lengths[index++] = symbol;
else { /* repeat instruction */
len = 0; /* assume repeating zeros */
if (symbol == 16) { /* repeat last length 3..6 times */
if (index == 0)
return -5; /* no last length! */
len = lengths[index - 1]; /* last length */
symbol = 3 + bits(s, 2);
}
else if (symbol == 17) /* repeat zero 3..10 times */
symbol = 3 + bits(s, 3);
else /* == 18, repeat zero 11..138 times */
symbol = 11 + bits(s, 7);
if (index + symbol > nlen + ndist)
return -6; /* too many lengths! */
while (symbol--) /* repeat last or zero symbol times */
lengths[index++] = len;
}
}
}
/* check for end-of-block code -- there better be one! */
if (lengths[256] == 0) return -9;
/* check for end-of-block code -- there better be one! */
if (lengths[256] == 0)
return -9;
/* build huffman table for literal/length codes */
err = construct(&lencode, lengths, nlen);
if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
return -7; /* incomplete code ok only for single length 1 code */
/* build huffman table for literal/length codes */
err = construct(&lencode, lengths, nlen);
if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
return -7; /* incomplete code ok only for single length 1 code */
/* build huffman table for distance codes */
err = construct(&distcode, lengths + nlen, ndist);
if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
return -8; /* incomplete code ok only for single length 1 code */
/* build huffman table for distance codes */
err = construct(&distcode, lengths + nlen, ndist);
if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
return -8; /* incomplete code ok only for single length 1 code */
/* decode data until end-of-block code */
return codes(s, &lencode, &distcode);
/* decode data until end-of-block code */
return codes(s, &lencode, &distcode);
}
/*
@ -756,47 +825,51 @@ static int dynamic(struct state *s) {
* block (if it was a fixed or dynamic block) are undefined and have no
* expected values to check.
*/
int puff(unsigned char *dest, /* pointer to destination pointer */
unsigned long *destlen, /* amount of output space */
const unsigned char *source, /* pointer to source data pointer */
unsigned long *sourcelen) /* amount of input available */
int puff(unsigned char *dest, /* pointer to destination pointer */
unsigned long *destlen, /* amount of output space */
const unsigned char *source, /* pointer to source data pointer */
unsigned long *sourcelen) /* amount of input available */
{
struct state s; /* input/output state */
int last, type; /* block information */
int err; /* return value */
struct state s; /* input/output state */
int last, type; /* block information */
int err; /* return value */
/* initialize output state */
s.out = dest;
s.outlen = *destlen; /* ignored if dest is NIL */
s.outcnt = 0;
/* initialize output state */
s.out = dest;
s.outlen = *destlen; /* ignored if dest is NIL */
s.outcnt = 0;
/* initialize input state */
s.in = source;
s.inlen = *sourcelen;
s.incnt = 0;
s.bitbuf = 0;
s.bitcnt = 0;
/* initialize input state */
s.in = source;
s.inlen = *sourcelen;
s.incnt = 0;
s.bitbuf = 0;
s.bitcnt = 0;
/* return if bits() or decode() tries to read past available input */
if (setjmp(s.env) != 0) /* if came back here via longjmp() */
err = 2; /* then skip do-loop, return error */
else {
/* process blocks until last block or error */
do {
last = bits(&s, 1); /* one if last block */
type = bits(&s, 2); /* block type 0..3 */
err = type == 0 ? stored(&s)
: (type == 1 ? fixed(&s)
: (type == 2 ? dynamic(&s)
: -1)); /* type == 3, invalid */
if (err != 0) break; /* return with error */
} while (!last);
}
/* return if bits() or decode() tries to read past available input */
if (setjmp(s.env) != 0) /* if came back here via longjmp() */
err = 2; /* then skip do-loop, return error */
else {
/* process blocks until last block or error */
do {
last = bits(&s, 1); /* one if last block */
type = bits(&s, 2); /* block type 0..3 */
err = type == 0 ?
stored(&s) :
(type == 1 ?
fixed(&s) :
(type == 2 ?
dynamic(&s) :
-1)); /* type == 3, invalid */
if (err != 0)
break; /* return with error */
} while (!last);
}
/* update the lengths and return */
if (err <= 0) {
*destlen = s.outcnt;
*sourcelen = s.incnt;
}
return err;
/* update the lengths and return */
if (err <= 0) {
*destlen = s.outcnt;
*sourcelen = s.incnt;
}
return err;
}

View file

@ -3,6 +3,10 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#ifndef NIL
#define NIL ((unsigned char *)0) /* for no output option */
#endif
int puff(unsigned char *dest, unsigned long *destlen,
const unsigned char *source, unsigned long *sourcelen);

View file

@ -1,3 +1,6 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
*/
/* trees.c -- output deflated data using Huffman coding
* Copyright (C) 1995-2021 Jean-loup Gailly
* detect_data_type() function provided freely by Cosmin Truta, 2006
@ -11,6 +14,11 @@
#include "libc/stdio/temp.h"
#include "libc/str/str.h"
#include "third_party/zlib/deflate.internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/*

View file

@ -1,91 +1,103 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Copyright 1995-2003,2010,2014,2016 Jean-loup Gailly and Mark Adler
Use of this source code is governed by the BSD-style licenses that can
be found in the third_party/zlib/LICENSE file.
*/
/* uncompr.c -- decompress a memory buffer
* Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#define ZLIB_INTERNAL
#include "third_party/zlib/internal.h"
#include "third_party/zlib/macros.internal.h"
#include "third_party/zlib/zlib.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/**
* Decompresses the source buffer into the destination buffer. *sourceLen is
* the byte length of the source buffer. Upon entry, *destLen is the total size
* of the destination buffer, which must be large enough to hold the entire
* uncompressed data. (The size of the uncompressed data must have been saved
* previously by the compressor and transmitted to the decompressor by some
* mechanism outside the scope of this compression library.) Upon exit,
* *destLen is the size of the decompressed data and *sourceLen is the number
* of source bytes consumed. Upon return, source + *sourceLen points to the
* first unused input byte.
*
* uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
* memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
* Z_DATA_ERROR if the input data was corrupted, including if the input data is
* an incomplete zlib stream.
*/
int uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong *sourceLen) {
z_stream stream;
int err;
const uInt max = (uInt)-1;
uLong len, left;
Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
/* @(#) $Id$ */
len = *sourceLen;
if (*destLen) {
left = *destLen;
*destLen = 0;
} else {
left = 1;
dest = buf;
}
/* ===========================================================================
Decompresses the source buffer into the destination buffer. *sourceLen is
the byte length of the source buffer. Upon entry, *destLen is the total size
of the destination buffer, which must be large enough to hold the entire
uncompressed data. (The size of the uncompressed data must have been saved
previously by the compressor and transmitted to the decompressor by some
mechanism outside the scope of this compression library.) Upon exit,
*destLen is the size of the decompressed data and *sourceLen is the number
of source bytes consumed. Upon return, source + *sourceLen points to the
first unused input byte.
stream.next_in = (const Bytef *)source;
stream.avail_in = 0;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
Z_DATA_ERROR if the input data was corrupted, including if the input data is
an incomplete zlib stream.
*/
int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong *sourceLen;
{
z_stream stream;
int err;
const uInt max = (uInt)-1;
uLong len, left;
Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
err = inflateInit(&stream);
if (err != Z_OK) return err;
stream.next_out = dest;
stream.avail_out = 0;
do {
if (stream.avail_out == 0) {
stream.avail_out = left > (uLong)max ? max : (uInt)left;
left -= stream.avail_out;
len = *sourceLen;
if (*destLen) {
left = *destLen;
*destLen = 0;
}
if (stream.avail_in == 0) {
stream.avail_in = len > (uLong)max ? max : (uInt)len;
len -= stream.avail_in;
else {
left = 1;
dest = buf;
}
err = inflate(&stream, Z_NO_FLUSH);
} while (err == Z_OK);
*sourceLen -= len + stream.avail_in;
if (dest != buf)
*destLen = stream.total_out;
else if (stream.total_out && err == Z_BUF_ERROR)
left = 1;
stream.next_in = (z_const Bytef *)source;
stream.avail_in = 0;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
inflateEnd(&stream);
return err == Z_STREAM_END
? Z_OK
: err == Z_NEED_DICT
? Z_DATA_ERROR
: err == Z_BUF_ERROR && left + stream.avail_out
? Z_DATA_ERROR
: err;
err = inflateInit(&stream);
if (err != Z_OK) return err;
stream.next_out = dest;
stream.avail_out = 0;
do {
if (stream.avail_out == 0) {
stream.avail_out = left > (uLong)max ? max : (uInt)left;
left -= stream.avail_out;
}
if (stream.avail_in == 0) {
stream.avail_in = len > (uLong)max ? max : (uInt)len;
len -= stream.avail_in;
}
err = inflate(&stream, Z_NO_FLUSH);
} while (err == Z_OK);
*sourceLen -= len + stream.avail_in;
if (dest != buf)
*destLen = stream.total_out;
else if (stream.total_out && err == Z_BUF_ERROR)
left = 1;
inflateEnd(&stream);
return err == Z_STREAM_END ? Z_OK :
err == Z_NEED_DICT ? Z_DATA_ERROR :
err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
err;
}
int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
uLong sourceLen) {
return uncompress2(dest, destLen, source, &sourceLen);
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
Bytef *dest;
uLongf *destLen;
const Bytef *source;
uLong sourceLen;
{
return uncompress2(dest, destLen, source, &sourceLen);
}

View file

@ -1,36 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/intrin/weaken.h"
#include "libc/limits.h"
#include "libc/mem/mem.h"
#include "third_party/zlib/zutil.internal.h"
void *zcalloc(void *opaque, uInt items, uInt size) {
size_t res;
if (__builtin_mul_overflow(items, size, &res)) return 0;
if (res > INT_MAX) return 0;
_npassert(_weaken(malloc));
return _weaken(malloc)(res);
}
void zcfree(void *opaque, void *ptr) {
_npassert(_weaken(free));
_weaken(free)(ptr);
}

View file

@ -1,136 +1,336 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Copyright 1995-2017 Jean-loup Gailly
Use of this source code is governed by the BSD-style licenses that can
be found in the third_party/zlib/LICENSE file.
*/
#include "libc/intrin/kprintf.h"
/* zutil.c -- target dependent utility functions for the compression library
* Copyright (C) 1995-2017 Jean-loup Gailly
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "libc/assert.h"
#include "libc/intrin/weaken.h"
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "third_party/zlib/internal.h"
#include "third_party/zlib/zutil.internal.h"
asm(".ident\t\"\\n\\n\
zlib (zlib License)\\n\
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
const char *const z_errmsg[10] = {
(const char *)"need dictionary", /* Z_NEED_DICT 2 */
(const char *)"stream end", /* Z_STREAM_END 1 */
(const char *)"", /* Z_OK 0 */
(const char *)"file error", /* Z_ERRNO (-1) */
(const char *)"stream error", /* Z_STREAM_ERROR (-2) */
(const char *)"data error", /* Z_DATA_ERROR (-3) */
(const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */
(const char *)"buffer error", /* Z_BUF_ERROR (-5) */
(const char *)"", /* Z_VERSION_ERROR (-6) */
(const char *)"",
/* @(#) $Id$ */
z_const char * const z_errmsg[10] = {
(z_const char *)"need dictionary", /* Z_NEED_DICT 2 */
(z_const char *)"stream end", /* Z_STREAM_END 1 */
(z_const char *)"", /* Z_OK 0 */
(z_const char *)"file error", /* Z_ERRNO (-1) */
(z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */
(z_const char *)"data error", /* Z_DATA_ERROR (-3) */
(z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */
(z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */
(z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
(z_const char *)""
};
const char *zlibVersion() {
return ZLIB_VERSION;
const char * ZEXPORT zlibVersion()
{
return ZLIB_VERSION;
}
uLong zlibCompileFlags() {
uLong flags;
flags = 0;
switch ((int)(sizeof(uInt))) {
case 2:
break;
case 4:
flags += 1;
break;
case 8:
flags += 2;
break;
default:
flags += 3;
}
switch ((int)(sizeof(uLong))) {
case 2:
break;
case 4:
flags += 1 << 2;
break;
case 8:
flags += 2 << 2;
break;
default:
flags += 3 << 2;
}
switch ((int)(sizeof(voidpf))) {
case 2:
break;
case 4:
flags += 1 << 4;
break;
case 8:
flags += 2 << 4;
break;
default:
flags += 3 << 4;
}
switch ((int)(sizeof(int64_t))) {
case 2:
break;
case 4:
flags += 1 << 6;
break;
case 8:
flags += 2 << 6;
break;
default:
flags += 3 << 6;
}
uLong ZEXPORT zlibCompileFlags()
{
uLong flags;
flags = 0;
switch ((int)(sizeof(uInt))) {
case 2: break;
case 4: flags += 1; break;
case 8: flags += 2; break;
default: flags += 3;
}
switch ((int)(sizeof(uLong))) {
case 2: break;
case 4: flags += 1 << 2; break;
case 8: flags += 2 << 2; break;
default: flags += 3 << 2;
}
switch ((int)(sizeof(voidpf))) {
case 2: break;
case 4: flags += 1 << 4; break;
case 8: flags += 2 << 4; break;
default: flags += 3 << 4;
}
switch ((int)(sizeof(z_off_t))) {
case 2: break;
case 4: flags += 1 << 6; break;
case 8: flags += 2 << 6; break;
default: flags += 3 << 6;
}
#ifdef ZLIB_DEBUG
flags += 1 << 8;
flags += 1 << 8;
#endif
#if defined(ASMV) || defined(ASMINF)
flags += 1 << 9;
flags += 1 << 9;
#endif
#ifdef ZLIB_WINAPI
flags += 1 << 10;
flags += 1 << 10;
#endif
#ifdef BUILDFIXED
flags += 1 << 12;
flags += 1 << 12;
#endif
#ifdef DYNAMIC_CRC_TABLE
flags += 1 << 13;
flags += 1 << 13;
#endif
#ifdef NO_GZCOMPRESS
flags += 1L << 16;
flags += 1L << 16;
#endif
#ifdef NO_GZIP
flags += 1L << 17;
flags += 1L << 17;
#endif
#ifdef PKZIP_BUG_WORKAROUND
flags += 1L << 20;
flags += 1L << 20;
#endif
#ifdef FASTEST
flags += 1L << 21;
flags += 1L << 21;
#endif
return flags;
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifdef NO_vsnprintf
flags += 1L << 25;
# ifdef HAS_vsprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_vsnprintf_void
flags += 1L << 26;
# endif
# endif
#else
flags += 1L << 24;
# ifdef NO_snprintf
flags += 1L << 25;
# ifdef HAS_sprintf_void
flags += 1L << 26;
# endif
# else
# ifdef HAS_snprintf_void
flags += 1L << 26;
# endif
# endif
#endif
return flags;
}
#ifdef ZLIB_DEBUG
#ifndef verbose
#define verbose 0
#endif
int z_verbose hidden = verbose;
# ifndef verbose
# define verbose 0
# endif
int ZLIB_INTERNAL z_verbose = verbose;
void z_error(const char *file, int line, char *m) {
kprintf("%s:%d: zlib panic: %s\n", file, line, m);
if (_weaken(__die)) _weaken(__die)();
_Exit(1);
void ZLIB_INTERNAL z_error (file, line, m)
const char *file;
char *m;
{
kprintf("%s:%d: zlib panic: %s\n", file, line, m);
if (_weaken(__die)) _weaken(__die)();
_Exit(1);
}
#endif
/**
* Exported to allow conversion of error code to string for compress()
* and uncompress()
/* exported to allow conversion of error code to string for compress() and
* uncompress()
*/
const char *zError(int err) {
return ERR_MSG(err);
const char * ZEXPORT zError(err)
int err;
{
return ERR_MSG(err);
}
#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
/* The older Microsoft C Run-Time Library for Windows CE doesn't have
* errno. We define it as a global variable to simplify porting.
* Its value is always 0 and should not be used.
*/
int errno = 0;
#endif
#ifndef HAVE_MEMCPY
void ZLIB_INTERNAL zmemcpy(dest, source, len)
Bytef* dest;
const Bytef* source;
uInt len;
{
if (len == 0) return;
do {
*dest++ = *source++; /* ??? to be unrolled */
} while (--len != 0);
}
int ZLIB_INTERNAL zmemcmp(s1, s2, len)
const Bytef* s1;
const Bytef* s2;
uInt len;
{
uInt j;
for (j = 0; j < len; j++) {
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
}
return 0;
}
void ZLIB_INTERNAL zmemzero(dest, len)
Bytef* dest;
uInt len;
{
if (len == 0) return;
do {
*dest++ = 0; /* ??? to be unrolled */
} while (--len != 0);
}
#endif
#ifndef Z_SOLO
#ifdef SYS16BIT
#ifdef __TURBOC__
/* Turbo C in 16-bit mode */
# define MY_ZCALLOC
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
* and farmalloc(64K) returns a pointer with an offset of 8, so we
* must fix the pointer. Warning: the pointer must be put back to its
* original form in order to free it, use zcfree().
*/
#define MAX_PTR 10
/* 10*64K = 640K */
local int next_ptr = 0;
typedef struct ptr_table_s {
voidpf org_ptr;
voidpf new_ptr;
} ptr_table;
local ptr_table table[MAX_PTR];
/* This table is used to remember the original form of pointers
* to large buffers (64K). Such pointers are normalized with a zero offset.
* Since MSDOS is not a preemptive multitasking OS, this table is not
* protected from concurrent access. This hack doesn't work anyway on
* a protected system like OS/2. Use Microsoft C instead.
*/
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
{
voidpf buf;
ulg bsize = (ulg)items*size;
(void)opaque;
/* If we allocate less than 65520 bytes, we assume that farmalloc
* will return a usable pointer which doesn't have to be normalized.
*/
if (bsize < 65520L) {
buf = farmalloc(bsize);
if (*(ush*)&buf != 0) return buf;
} else {
buf = farmalloc(bsize + 16L);
}
if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
table[next_ptr].org_ptr = buf;
/* Normalize the pointer to seg:0 */
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
*(ush*)&buf = 0;
table[next_ptr++].new_ptr = buf;
return buf;
}
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
{
int n;
(void)opaque;
if (*(ush*)&ptr != 0) { /* object < 64K */
farfree(ptr);
return;
}
/* Find the original pointer */
for (n = 0; n < next_ptr; n++) {
if (ptr != table[n].new_ptr) continue;
farfree(table[n].org_ptr);
while (++n < next_ptr) {
table[n-1] = table[n];
}
next_ptr--;
return;
}
Assert(0, "zcfree: ptr not found");
}
#endif /* __TURBOC__ */
#ifdef M_I86
/* Microsoft C in 16-bit mode */
# define MY_ZCALLOC
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
# define _halloc halloc
# define _hfree hfree
#endif
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
{
(void)opaque;
return _halloc((long)items, size);
}
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
{
(void)opaque;
_hfree(ptr);
}
#endif /* M_I86 */
#endif /* SYS16BIT */
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
#ifndef STDC
extern voidp malloc OF((uInt size));
extern voidp calloc OF((uInt items, uInt size));
extern void free OF((voidpf ptr));
#endif
voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
voidpf opaque;
unsigned items;
unsigned size;
{
(void)opaque;
_npassert(_weaken(malloc));
return _weaken(malloc)(items * size);
}
void ZLIB_INTERNAL zcfree (opaque, ptr)
voidpf opaque;
voidpf ptr;
{
(void)opaque;
_npassert(_weaken(free));
_weaken(free)(ptr);
}
#endif /* MY_ZCALLOC */
#endif /* !Z_SOLO */

View file

@ -24,6 +24,10 @@
#define OS_CODE 3 /* assume Unix */
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
#define HAVE_MEMCPY
#endif
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_