diff options
Diffstat (limited to 'sys/contrib/zstd/zlibWrapper/examples/minigzip.c')
| -rw-r--r-- | sys/contrib/zstd/zlibWrapper/examples/minigzip.c | 654 | 
1 files changed, 654 insertions, 0 deletions
diff --git a/sys/contrib/zstd/zlibWrapper/examples/minigzip.c b/sys/contrib/zstd/zlibWrapper/examples/minigzip.c new file mode 100644 index 000000000000..521d047117c5 --- /dev/null +++ b/sys/contrib/zstd/zlibWrapper/examples/minigzip.c @@ -0,0 +1,654 @@ +/* minigzip.c contains minimal changes required to be compiled with zlibWrapper: + * - #include "zlib.h" was changed to #include "zstd_zlibwrapper.h"        */ + +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. + * For conditions of distribution and use, see http://www.zlib.net/zlib_license.html + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +/* @(#) $Id$ */ + +#include "zstd_zlibwrapper.h" +#include <stdio.h> + +#ifdef STDC +#  include <string.h> +#  include <stdlib.h> +#endif + +#ifdef USE_MMAP +#  include <sys/types.h> +#  include <sys/mman.h> +#  include <sys/stat.h> +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +#  include <fcntl.h> +#  include <io.h> +#  ifdef UNDER_CE +#    include <stdlib.h> +#  endif +#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +#  define SET_BINARY_MODE(file) +#endif + +#ifdef _MSC_VER +#  define snprintf _snprintf +#endif + +#ifdef VMS +#  define unlink delete +#  define GZ_SUFFIX "-gz" +#endif +#ifdef RISCOS +#  define unlink remove +#  define GZ_SUFFIX "-gz" +#  define fileno(file) file->__file +#endif +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +#  include <unix.h> /* for fileno */ +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ +  extern int unlink OF((const char *)); +#endif +#endif + +#if defined(UNDER_CE) +#  include <windows.h> +#  define perror(s) pwinerror(s) + +/* Map the Windows error number in ERROR to a locale-dependent error +   message string and return a pointer to it.  Typically, the values +   for ERROR come from GetLastError. + +   The string pointed to shall not be modified by the application, +   but may be overwritten by a subsequent call to strwinerror + +   The strwinerror function does not change the current setting +   of GetLastError.  */ + +static char *strwinerror (error) +     DWORD error; +{ +    static char buf[1024]; + +    wchar_t *msgbuf; +    DWORD lasterr = GetLastError(); +    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM +        | FORMAT_MESSAGE_ALLOCATE_BUFFER, +        NULL, +        error, +        0, /* Default language */ +        (LPVOID)&msgbuf, +        0, +        NULL); +    if (chars != 0) { +        /* If there is an \r\n appended, zap it.  */ +        if (chars >= 2 +            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { +            chars -= 2; +            msgbuf[chars] = 0; +        } + +        if (chars > sizeof (buf) - 1) { +            chars = sizeof (buf) - 1; +            msgbuf[chars] = 0; +        } + +        wcstombs(buf, msgbuf, chars + 1); +        LocalFree(msgbuf); +    } +    else { +        sprintf(buf, "unknown win32 error (%ld)", error); +    } + +    SetLastError(lasterr); +    return buf; +} + +static void pwinerror (s) +    const char *s; +{ +    if (s && *s) +        fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ())); +    else +        fprintf(stderr, "%s\n", strwinerror(GetLastError ())); +} + +#endif /* UNDER_CE */ + +#ifndef GZ_SUFFIX +#  define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN      16384 +#define MAX_NAME_LEN 1024 + +#ifdef MAXSEG_64K +#  define local static +   /* Needed for systems with limitation on stack size. */ +#else +#  define local +#endif + +#ifdef Z_SOLO +/* for Z_SOLO, create simplified gz* functions using deflate and inflate */ + +#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE) +#  include <unistd.h>       /* for unlink() */ +#endif + +void *myalloc OF((void *, unsigned, unsigned)); +void myfree OF((void *, void *)); + +void *myalloc(q, n, m) +    void *q; +    unsigned n, m; +{ +    q = Z_NULL; +    return calloc(n, m); +} + +void myfree(q, p) +    void *q, *p; +{ +    q = Z_NULL; +    free(p); +} + +typedef struct gzFile_s { +    FILE *file; +    int write; +    int err; +    char *msg; +    z_stream strm; +} *gzFile; + +gzFile gzopen OF((const char *, const char *)); +gzFile gzdopen OF((int, const char *)); +gzFile gz_open OF((const char *, int, const char *)); + +gzFile gzopen(path, mode) +const char *path; +const char *mode; +{ +    return gz_open(path, -1, mode); +} + +gzFile gzdopen(fd, mode) +int fd; +const char *mode; +{ +    return gz_open(NULL, fd, mode); +} + +gzFile gz_open(path, fd, mode) +    const char *path; +    int fd; +    const char *mode; +{ +    gzFile gz; +    int ret; + +    gz = malloc(sizeof(struct gzFile_s)); +    if (gz == NULL) +        return NULL; +    gz->write = strchr(mode, 'w') != NULL; +    gz->strm.zalloc = myalloc; +    gz->strm.zfree = myfree; +    gz->strm.opaque = Z_NULL; +    if (gz->write) +        ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0); +    else { +        gz->strm.next_in = 0; +        gz->strm.avail_in = Z_NULL; +        ret = inflateInit2(&(gz->strm), 15 + 16); +    } +    if (ret != Z_OK) { +        free(gz); +        return NULL; +    } +    gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") : +                              fopen(path, gz->write ? "wb" : "rb"); +    if (gz->file == NULL) { +        gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm)); +        free(gz); +        return NULL; +    } +    gz->err = 0; +    gz->msg = ""; +    return gz; +} + +int gzwrite OF((gzFile, const void *, unsigned)); + +int gzwrite(gz, buf, len) +    gzFile gz; +    const void *buf; +    unsigned len; +{ +    z_stream *strm; +    unsigned char out[BUFLEN]; + +    if (gz == NULL || !gz->write) +        return 0; +    strm = &(gz->strm); +    strm->next_in = (void *)buf; +    strm->avail_in = len; +    do { +        strm->next_out = out; +        strm->avail_out = BUFLEN; +        (void)deflate(strm, Z_NO_FLUSH); +        fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); +    } while (strm->avail_out == 0); +    return len; +} + +int gzread OF((gzFile, void *, unsigned)); + +int gzread(gz, buf, len) +    gzFile gz; +    void *buf; +    unsigned len; +{ +    int ret; +    unsigned got; +    unsigned char in[1]; +    z_stream *strm; + +    if (gz == NULL || gz->write) +        return 0; +    if (gz->err) +        return 0; +    strm = &(gz->strm); +    strm->next_out = (void *)buf; +    strm->avail_out = len; +    do { +        got = fread(in, 1, 1, gz->file); +        if (got == 0) +            break; +        strm->next_in = in; +        strm->avail_in = 1; +        ret = inflate(strm, Z_NO_FLUSH); +        if (ret == Z_DATA_ERROR) { +            gz->err = Z_DATA_ERROR; +            gz->msg = strm->msg; +            return 0; +        } +        if (ret == Z_STREAM_END) +            inflateReset(strm); +    } while (strm->avail_out); +    return len - strm->avail_out; +} + +int gzclose OF((gzFile)); + +int gzclose(gz) +    gzFile gz; +{ +    z_stream *strm; +    unsigned char out[BUFLEN]; + +    if (gz == NULL) +        return Z_STREAM_ERROR; +    strm = &(gz->strm); +    if (gz->write) { +        strm->next_in = Z_NULL; +        strm->avail_in = 0; +        do { +            strm->next_out = out; +            strm->avail_out = BUFLEN; +            (void)deflate(strm, Z_FINISH); +            fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); +        } while (strm->avail_out == 0); +        deflateEnd(strm); +    } +    else +        inflateEnd(strm); +    fclose(gz->file); +    free(gz); +    return Z_OK; +} + +const char *gzerror OF((gzFile, int *)); + +const char *gzerror(gz, err) +    gzFile gz; +    int *err; +{ +    *err = gz->err; +    return gz->msg; +} + +#endif + +char *prog; + +void error            OF((const char *msg)); +void gz_compress      OF((FILE   *in, gzFile out)); +#ifdef USE_MMAP +int  gz_compress_mmap OF((FILE   *in, gzFile out)); +#endif +void gz_uncompress    OF((gzFile in, FILE   *out)); +void file_compress    OF((char  *file, char *mode)); +void file_uncompress  OF((char  *file)); +int  main             OF((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) +    const char *msg; +{ +    fprintf(stderr, "%s: %s\n", prog, msg); +    exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(in, out) +    FILE   *in; +    gzFile out; +{ +    local char buf[BUFLEN]; +    int len; +    int err; + +#ifdef USE_MMAP +    /* Try first compressing with mmap. If mmap fails (minigzip used in a +     * pipe), use the normal fread loop. +     */ +    if (gz_compress_mmap(in, out) == Z_OK) return; +#endif +    for (;;) { +        len = (int)fread(buf, 1, sizeof(buf), in); +        if (ferror(in)) { +            perror("fread"); +            exit(1); +        } +        if (len == 0) break; + +        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); +    } +    fclose(in); +    if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(in, out) +    FILE   *in; +    gzFile out; +{ +    int len; +    int err; +    int ifd = fileno(in); +    caddr_t buf;    /* mmap'ed buffer for the entire input file */ +    off_t buf_len;  /* length of the input file */ +    struct stat sb; + +    /* Determine the size of the file, needed for mmap: */ +    if (fstat(ifd, &sb) < 0) return Z_ERRNO; +    buf_len = sb.st_size; +    if (buf_len <= 0) return Z_ERRNO; + +    /* Now do the actual mmap: */ +    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); +    if (buf == (caddr_t)(-1)) return Z_ERRNO; + +    /* Compress the whole file at once: */ +    len = gzwrite(out, (char *)buf, (unsigned)buf_len); + +    if (len != (int)buf_len) error(gzerror(out, &err)); + +    munmap(buf, buf_len); +    fclose(in); +    if (gzclose(out) != Z_OK) error("failed gzclose"); +    return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) +    gzFile in; +    FILE   *out; +{ +    local char buf[BUFLEN]; +    int len; +    int err; + +    for (;;) { +        len = gzread(in, buf, sizeof(buf)); +        if (len < 0) error (gzerror(in, &err)); +        if (len == 0) break; + +        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { +            error("failed fwrite"); +        } +    } +    if (fclose(out)) error("failed fclose"); + +    if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file, mode) +    char  *file; +    char  *mode; +{ +    local char outfile[MAX_NAME_LEN]; +    FILE  *in; +    gzFile out; + +    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { +        fprintf(stderr, "%s: filename too long\n", prog); +        exit(1); +    } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) +    snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); +#else +    strcpy(outfile, file); +    strcat(outfile, GZ_SUFFIX); +#endif + +    in = fopen(file, "rb"); +    if (in == NULL) { +        perror(file); +        exit(1); +    } +    out = gzopen(outfile, mode); +    if (out == NULL) { +        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); +        exit(1); +    } +    gz_compress(in, out); + +    unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) +    char  *file; +{ +    local char buf[MAX_NAME_LEN]; +    char *infile, *outfile; +    FILE  *out; +    gzFile in; +    size_t len = strlen(file); + +    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { +        fprintf(stderr, "%s: filename too long\n", prog); +        exit(1); +    } + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) +    snprintf(buf, sizeof(buf), "%s", file); +#else +    strcpy(buf, file); +#endif + +    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { +        infile = file; +        outfile = buf; +        outfile[len-3] = '\0'; +    } else { +        outfile = file; +        infile = buf; +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) +        snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); +#else +        strcat(infile, GZ_SUFFIX); +#endif +    } +    in = gzopen(infile, "rb"); +    if (in == NULL) { +        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); +        exit(1); +    } +    out = fopen(outfile, "wb"); +    if (out == NULL) { +        perror(file); +        exit(1); +    } + +    gz_uncompress(in, out); + +    unlink(infile); +} + + +/* =========================================================================== + * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] + *   -c : write to standard output + *   -d : decompress + *   -f : compress with Z_FILTERED + *   -h : compress with Z_HUFFMAN_ONLY + *   -r : compress with Z_RLE + *   -1 to -9 : compression level + */ + +int main(argc, argv) +    int argc; +    char *argv[]; +{ +    int copyout = 0; +    int uncompr = 0; +    gzFile file; +    char *bname, outmode[20]; + +#if !defined(NO_snprintf) && !defined(NO_vsnprintf) +    snprintf(outmode, sizeof(outmode), "%s", "wb6 "); +#else +    strcpy(outmode, "wb6 "); +#endif + +    prog = argv[0]; +    bname = strrchr(argv[0], '/'); +    if (bname) +      bname++; +    else +      bname = argv[0]; +    argc--, argv++; + +    if (!strcmp(bname, "gunzip")) +      uncompr = 1; +    else if (!strcmp(bname, "zcat")) +      copyout = uncompr = 1; + +    while (argc > 0) { +      if (strcmp(*argv, "-c") == 0) +        copyout = 1; +      else if (strcmp(*argv, "-d") == 0) +        uncompr = 1; +      else if (strcmp(*argv, "-f") == 0) +        outmode[3] = 'f'; +      else if (strcmp(*argv, "-h") == 0) +        outmode[3] = 'h'; +      else if (strcmp(*argv, "-r") == 0) +        outmode[3] = 'R'; +      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && +               (*argv)[2] == 0) +        outmode[2] = (*argv)[1]; +      else +        break; +      argc--, argv++; +    } +    if (outmode[3] == ' ') +        outmode[3] = 0; +    if (argc == 0) { +        SET_BINARY_MODE(stdin); +        SET_BINARY_MODE(stdout); +        if (uncompr) { +            file = gzdopen(fileno(stdin), "rb"); +            if (file == NULL) error("can't gzdopen stdin"); +            gz_uncompress(file, stdout); +        } else { +            file = gzdopen(fileno(stdout), outmode); +            if (file == NULL) error("can't gzdopen stdout"); +            gz_compress(stdin, file); +        } +    } else { +        if (copyout) { +            SET_BINARY_MODE(stdout); +        } +        do { +            if (uncompr) { +                if (copyout) { +                    file = gzopen(*argv, "rb"); +                    if (file == NULL) +                        fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); +                    else +                        gz_uncompress(file, stdout); +                } else { +                    file_uncompress(*argv); +                } +            } else { +                if (copyout) { +                    FILE * in = fopen(*argv, "rb"); + +                    if (in == NULL) { +                        perror(*argv); +                    } else { +                        file = gzdopen(fileno(stdout), outmode); +                        if (file == NULL) error("can't gzdopen stdout"); + +                        gz_compress(in, file); +                    } + +                } else { +                    file_compress(*argv, outmode); +                } +            } +        } while (argv++, --argc); +    } +    return 0; +}  | 
