RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  j...@rpm5.org
  Module: rpm                              Date:   01-Jun-2017 19:39:56
  Branch: rpm-5_4                          Handle: 2017060117395600

  Added files:              (Branch: rpm-5_4)
    rpm/rpmio               tzstd.c
  Modified files:           (Branch: rpm-5_4)
    rpm/rpmio               Makefile.am rpmmacro.h zstio.c

  Log:
    - zstd: add test program.

  Summary:
    Revision    Changes     Path
    1.293.2.84  +4  -1      rpm/rpmio/Makefile.am
    2.56.4.12   +11 -10     rpm/rpmio/rpmmacro.h
    1.1.2.1     +649 -0     rpm/rpmio/tzstd.c
    1.1.2.2     +40 -28     rpm/rpmio/zstio.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmio/Makefile.am
  ============================================================================
  $ cvs diff -u -r1.293.2.83 -r1.293.2.84 Makefile.am
  --- rpm/rpmio/Makefile.am     30 May 2017 23:48:23 -0000      1.293.2.83
  +++ rpm/rpmio/Makefile.am     1 Jun 2017 17:39:56 -0000       1.293.2.84
  @@ -20,7 +20,7 @@
        microjson.c mongoc-counters.defs
   
   EXTRA_PROGRAMS = rpmcpio rpmdpkg rpmtar rpmz
  -EXTRA_PROGRAMS += bdes duk thtml tinv tkey tmacro tmq tpw turg
  +EXTRA_PROGRAMS += bdes duk thtml tinv tkey tmacro tmq tpw turg tzstd
   noinst_PROGRAMS = tjsmn tmqtt
   
   EXTRA_PROGRAMS += bsdiff bspatch fanotify pcrsed rpmborg rpmcurl \
  @@ -679,6 +679,9 @@
   turg_SOURCES = turg.c
   turg_LDADD = $(RPMIO_LDADD_COMMON)
   
  +tzstd_SOURCES = tzstd.c
  +tzstd_LDADD = $(RPMIO_LDADD_COMMON)
  +
   github_SOURCES = tjson.c
   github_CFLAGS = -Wall -Werror -std=gnu99 -O2 -DJSMN_GITHUB
   github_LDADD = -lcurl
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmmacro.h
  ============================================================================
  $ cvs diff -u -r2.56.4.11 -r2.56.4.12 rpmmacro.h
  --- rpm/rpmio/rpmmacro.h      6 Jul 2016 14:25:43 -0000       2.56.4.11
  +++ rpm/rpmio/rpmmacro.h      1 Jun 2017 17:39:56 -0000       2.56.4.12
  @@ -180,16 +180,17 @@
   void rpmFreeMacros(MacroContext mc);
   
   typedef enum rpmCompressedMagic_e {
  -    COMPRESSED_NOT           = 0,    /*!< not compressed */
  -    COMPRESSED_OTHER         = 1,    /*!< gzip can handle */
  -    COMPRESSED_BZIP2         = 2,    /*!< bzip2 can handle */
  -    COMPRESSED_ZIP           = 3,    /*!< unzip can handle */
  -    COMPRESSED_LZOP          = 4,    /*!< lzop can handle */
  -    COMPRESSED_LZMA          = 5,    /*!< lzma can handle */
  -    COMPRESSED_XZ            = 6,    /*!< xz can handle */
  -    COMPRESSED_LRZIP         = 7,    /*!< lrzip can handle */
  -    COMPRESSED_LZIP          = 8,    /*!< lzip can handle */
  -    COMPRESSED_7ZIP          = 9,    /*!< 7zip can handle */
  +    COMPRESSED_NOT           =  0,   /*!< not compressed */
  +    COMPRESSED_OTHER         =  1,   /*!< gzip can handle */
  +    COMPRESSED_BZIP2         =  2,   /*!< bzip2 can handle */
  +    COMPRESSED_ZIP           =  3,   /*!< unzip can handle */
  +    COMPRESSED_LZOP          =  4,   /*!< lzop can handle */
  +    COMPRESSED_LZMA          =  5,   /*!< lzma can handle */
  +    COMPRESSED_XZ            =  6,   /*!< xz can handle */
  +    COMPRESSED_LRZIP         =  7,   /*!< lrzip can handle */
  +    COMPRESSED_LZIP          =  8,   /*!< lzip can handle */
  +    COMPRESSED_7ZIP          =  9,   /*!< 7zip can handle */
  +    COMPRESSED_ZSTD          = 10,   /*!< 7zip can handle */
   } rpmCompressedMagic;
   
   /**
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/tzstd.c
  ============================================================================
  $ cvs diff -u -r0 -r1.1.2.1 tzstd.c
  --- /dev/null 2017-06-01 19:34:23.000000000 +0200
  +++ tzstd.c   2017-06-01 19:39:56.447439530 +0200
  @@ -0,0 +1,649 @@
  +/**
  + * Copyright 2016-present, Yann Collet, Facebook, Inc.
  + * All rights reserved.
  + *
  + * This source code is licensed under the license found in the
  + * LICENSE-examples file in the root directory of this source tree.
  + */
  +
  +#include "system.h"
  +
  +#include "rpmio_internal.h"
  +#include <rpmlog.h>
  +#include <rpmmacro.h>
  +#include <poptIO.h>
  +#include <argv.h>
  +#include <yarn.h>
  +#define PEEK(_bolt)  yarnPeekLock(_bolt)
  +
  +#if defined(WITH_ZSTD)
  +#include <zstd.h>            // presumes zstd library is installed
  +#endif
  +
  +#include "debug.h"
  +
  +static int _debug;
  +
  +int _rpmzsf_debug = -1;
  +
  +#define SPEW(_fmt, ...) \
  +    if ((zsf && ZSF_ISSET(DEBUG)) || _rpmzsf_debug || _rpmio_debug) \
  +     fprintf(stderr, _fmt, __VA_ARGS__)
  +
  +#undef       COMPRESSOR
  +
  +typedef      struct rpmzsf_s * rpmzsf;
  +struct rpmzsf_s {
  +    struct rpmioItem_s _item;        /*!< usage mutex and pool identifier. */
  +    const char * path;               /*!> open path. */
  +    const char * fmode;
  +    unsigned flags;
  +#define      RPMZSF_FLAGS_NONE               (0)
  +#define      RPMZSF_FLAGS_DEBUG              (1<<0)
  +#define      RPMZSF_FLAGS_DECOMPRESS         (1<<1)
  +#define      ZSF_ISSET(_foo)         (zsf->flags & RPMZSF_FLAGS_##_foo)
  +    int fdno;
  +    int oflags;                      /*!< open flags. */
  +    int omode;                       /*!< open mode. */
  +
  +    size_t nb;
  +    size_t nr;
  +    size_t nw;
  +    int level;
  +
  +    FILE * ifp;
  +    FILE * ofp;
  +    size_t nib;      /* can always read one full block */
  +    void * ib;
  +    size_t nob;      /* can always flush a full block */
  +    void * ob;
  +    ZSTD_CStream * cstream;
  +    ZSTD_DStream * dstream;
  +    ZSTD_inBuffer zib;
  +    ZSTD_outBuffer zob;
  +};
  +
  +static void rpmzsfDump(const char * msg, rpmzsf zsf)
  +{
  +    if (msg) fprintf(stderr, "========================== %s\n", msg);
  +    if (zsf) {
  +#define PRINT(_fmt, _foo) \
  +    {   fprintf(stderr, "%25s: %"#_fmt"\n", #_foo, zsf->_foo); }
  +     PRINT(s,  path);
  +     PRINT(s,  fmode);
  +     PRINT(x,  flags);
  +     PRINT(d,  fdno);
  +     PRINT(x,  oflags);
  +     PRINT(o,  omode);
  +
  +     PRINT(d,  level);
  +     PRINT(zu, nb);
  +
  +     if (zsf->cstream) {
  +         PRINT(p,  cstream);
  +         PRINT(p,  ofp);
  +         PRINT(p,  zob.dst);
  +         PRINT(p,  ob);
  +         PRINT(zu, zob.size);
  +         PRINT(zu, nob);
  +         PRINT(zu, zob.pos);
  +         PRINT(zu, nw);
  +     }
  +
  +     if (zsf->dstream) {
  +         PRINT(p,  dstream);
  +         PRINT(p,  ifp);
  +         PRINT(p,  zib.src);
  +         PRINT(p,  ib);
  +         PRINT(zu, zib.size);
  +         PRINT(zu, nib);
  +         PRINT(zu, zib.pos);
  +         PRINT(zu, nr);
  +     }
  +#undef       PRINT
  +
  +    }
  +}
  +
  +#define rpmzsfLink(_zsf)     \
  +    ((rpmzsf)rpmioLinkPoolItem((rpmioItem)(_zsf), __FUNCTION__, __FILE__, 
__LINE__))
  +
  +#define rpmzsfFree(_zsf)     \
  +    ((rpmzsf)rpmioFreePoolItem((rpmioItem)(_zsf), __FUNCTION__, __FILE__, 
__LINE__))
  +/* =============================================================== */
  +static char * rpmzsfDbug(void *_zsf, char *b, size_t nb)
  +{
  +    rpmzsf zsf = (rpmzsf) _zsf;
  +    size_t len = strlen(b);
  +    char * be = b + len;
  +    rpmioItem item = (rpmioItem) zsf;
  +    long use;
  +
  +    if (zsf && (use = PEEK(item->use)) > 0) {
  +     int colorize = isatty(fileno(stderr));
  +#define ANSI_BRIGHT_BLUE     "\x1b[34;1m"
  +#define ANSI_RESET           "\x1b[0m"
  +     *be++ = '\n';
  +     if (colorize) be = stpcpy(be, ANSI_BRIGHT_BLUE);
  +     be += sprintf(be, "========================== zsf(%p) use %ld\n",
  +             zsf, use);
  +#define PRINT(_fmt, _foo) \
  +    {        be += sprintf(be, "%25s: %"#_fmt"\n", #_foo, zsf->_foo); }
  +     PRINT(s,  path);
  +     PRINT(s,  fmode);
  +     PRINT(x,  flags);
  +     PRINT(d,  fdno);
  +     PRINT(x,  oflags);
  +     PRINT(o,  omode);
  +
  +     PRINT(d,  level);
  +     PRINT(zu, nb);
  +
  +     if (zsf->cstream) {
  +         PRINT(p,  cstream);
  +         PRINT(p,  ofp);
  +         PRINT(p,  zob.dst);
  +         PRINT(p,  ob);
  +         PRINT(zu, zob.size);
  +         PRINT(zu, nob);
  +         PRINT(zu, zob.pos);
  +         PRINT(zu, nw);
  +     }
  +
  +     if (zsf->dstream) {
  +         PRINT(p,  dstream);
  +         PRINT(p,  ifp);
  +         PRINT(p,  zib.src);
  +         PRINT(p,  ib);
  +         PRINT(zu, zib.size);
  +         PRINT(zu, nib);
  +         PRINT(zu, zib.pos);
  +         PRINT(zu, nr);
  +     }
  +
  +#undef       PRINT
  +     be--;
  +     if (colorize) be = stpcpy(be, ANSI_RESET);
  +     *be = '\0';
  +    }
  +    return b;
  +}
  +
  +static void rpmzsfInit(void *_zsf)
  +{
  +}
  +
  +
  +static void rpmzsfFini(void *_zsf)
  +{
  +    rpmzsf zsf = (rpmzsf) _zsf;
  +    if (zsf) {
  +     if (zsf->path)
  +         zsf->path = _free(zsf->path);
  +     if (zsf->fmode)
  +         zsf->fmode = _free(zsf->fmode);
  +     zsf->flags = 0;
  +     zsf->fdno = -1;
  +     zsf->oflags = 0;
  +     zsf->omode = 0;
  +
  +     zsf->nb = 0;
  +     zsf->nr = 0;
  +     zsf->nw = 0;
  +     zsf->level = 0;
  +
  +     if (zsf->ifp && fileno(zsf->ifp) > 2)
  +         fclose(zsf->ifp);
  +     zsf->ifp = NULL;
  +     if (zsf->ib)
  +         zsf->ib = _free(zsf->ib);
  +     zsf->nib = 0;
  +
  +     if (zsf->ofp && fileno(zsf->ofp) > 2)
  +         fclose(zsf->ofp);
  +     zsf->ofp = NULL;
  +     if (zsf->ob)
  +         zsf->ob = _free(zsf->ob);
  +     zsf->nob = 0;
  +
  +     if (zsf->cstream)
  +         ZSTD_freeCStream(zsf->cstream);
  +     zsf->cstream = NULL;
  +     if (zsf->dstream)
  +         ZSTD_freeDStream(zsf->dstream);
  +     zsf->dstream = NULL;
  +
  +     zsf->zib.src = NULL;
  +     zsf->zib.pos = 0;
  +     zsf->zib.size = 0;
  +     zsf->zob.dst = NULL;
  +     zsf->zob.pos = 0;
  +     zsf->zob.size = 0;
  +    }
  +}
  +
  +RPMIOPOOL_MODULE(zsf)
  +
  +static rpmzsf rpmzsfNew(const char *path, const char *fmode, int fdno, 
unsigned flags)
  +{
  +    rpmzsf zsf = rpmzsfGetPool(_rpmzsfPool);
  +assert(fmode != NULL);               /* XXX return NULL instead? */
  +
  +    const char * s = fmode;
  +    int c;
  +    int oflags = 0;
  +    int omode = 0644;
  +    int level = 3;   /* XXX zstd permits 1-19 (default: 3) */
  +
  +    switch ((c = *s++)) {
  +    case 'a':
  +     oflags = O_WRONLY | O_CREAT | O_APPEND;
  +     break;
  +    case 'w':
  +     oflags = O_WRONLY | O_CREAT | O_TRUNC;
  +     break;
  +    case 'r':
  +     oflags = O_RDONLY;
  +     break;
  +    }
  +     
  +    while ((c = *s++) != 0) {
  +     switch (c) {
  +     case '.':
  +         break;
  +     case '+':
  +         oflags &= ~(O_RDONLY|O_WRONLY);
  +         oflags |= O_RDWR;
  +         continue;
  +         break;
  +     case 'c':       /* XXX no cancel */
  +         continue;
  +         break;
  +     case 'm':       /* XXX mmap */
  +         continue;
  +         break;
  +     case 'e':       /* O_CLOEXEC */
  +         oflags |= O_CLOEXEC;
  +         continue;
  +         break;
  +     case 'n':       /* XXX O_NONBLOCK */
  +         oflags |= O_NONBLOCK;
  +         continue;
  +         break;
  +     case 't':       /* XXX O_TRUNC */
  +         continue;
  +         break;
  +     case 'x':
  +         oflags |= O_EXCL;
  +         continue;
  +         break;
  +     case '?':
  +         flags |= RPMZSF_FLAGS_DEBUG;
  +         continue;
  +         break;
  +     default:
  +         if (c >= (int)'0' && c <= (int)'9') {
  +             level = strtol(s-1, (char **)&s, 10);
  +assert(level >= 1 && level <= 19);
  +         }
  +         continue;
  +         break;
  +     }
  +     break;
  +    }
  +
  +    zsf->path = xstrdup(path);
  +    zsf->fmode = xstrdup(fmode);
  +    zsf->fdno = fdno;
  +    zsf->flags = flags;
  +
  +    zsf->oflags = oflags;
  +    zsf->omode = omode;
  +
  +    zsf->level = level;
  +
  +    if (ZSF_ISSET(DECOMPRESS)) {     /* decompress */
  +     zsf->dstream = ZSTD_createDStream();
  +     if (zsf->dstream == NULL) {
  +         fprintf(stderr, "ZSTD_createDStream() error \n");
  +         exit(10);
  +     }
  +     /*
  +      * In more complex scenarios, a file may consist of multiple
  +      * appended frames (ex : pzstd).
  +      * The following example decompresses only the first frame.
  +      * It is compatible with other provided streaming examples.
  +      */
  +     zsf->nb = ZSTD_initDStream(zsf->dstream);
  +     if (ZSTD_isError(zsf->nb)) {
  +         fprintf(stderr, "ZSTD_initDStream() error : %s \n",
  +             ZSTD_getErrorName(zsf->nb));
  +         exit(11);   /* XXX */
  +     }
  +     zsf->nib = ZSTD_CStreamInSize();
  +     zsf->ib = xmalloc(zsf->nib);
  +#ifdef       NOTYET
  +     zsf->nob = BUFSIZ;
  +     zsf->ob = xmalloc(zsf->nob);
  +#else
  +     zsf->nob = ZSTD_CStreamOutSize();
  +     zsf->ob = xmalloc(zsf->nob);
  +#endif
  +    } else {                         /* compress */
  +     zsf->cstream = ZSTD_createCStream();
  +     if (zsf->cstream == NULL) {
  +         fprintf(stderr, "ZSTD_createCStream() error \n");
  +         exit(10);
  +     }
  +     zsf->nb = ZSTD_initCStream(zsf->cstream, level);
  +     if (ZSTD_isError(zsf->nb)) {
  +         fprintf(stderr, "ZSTD_initCStream() error : %s \n",
  +             ZSTD_getErrorName(zsf->nb));
  +         exit(11);   /* XXX */
  +     }
  +#ifdef       NOTYET
  +     zsf->nib = BUFSIZ;
  +     zsf->ib = xmalloc(zsf->nib);
  +#else
  +     zsf->nib = ZSTD_CStreamInSize();
  +     zsf->ib = xmalloc(zsf->nib);
  +#endif
  +     zsf->nob = ZSTD_CStreamOutSize();
  +     zsf->ob = xmalloc(zsf->nob);
  +    }
  +
  +    return rpmzsfLink(zsf);
  +}
  +
  +static int rpmzsfFlush(rpmzsf zsf)
  +{
  +    int rc = -2;
  +
  +    if (ZSF_ISSET(DECOMPRESS)) {     /* decompress */
  +assert(zsf->dstream);
  +    } else {                         /* compress */
  +assert(zsf->cstream);
  +     /* close frame */
  +     zsf->zob.dst  = zsf->ob;
  +     zsf->zob.size = zsf->nob;
  +     zsf->zob.pos  = 0;
  +     /* XXX nremain != 0 on small output buffers. Loop. */
  +     size_t nremain = ZSTD_flushStream(zsf->cstream, &zsf->zob);
  +     if (nremain) {
  +fprintf(stderr, "not fully flushed");
  +         rc = -1;
  +     } else {
  +         zsf->nw = fwrite(zsf->ob, 1, zsf->zob.pos, zsf->ofp);
  +assert(zsf->nw == zsf->zob.pos);
  +SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zsf->ob, zsf->zob.pos, 
zsf->ofp, zsf->nw);
  +         rc = 0;
  +     }
  +    }
  +
  +SPEW("<--\t%s(%p) rc %d\n", __FUNCTION__, zsf, rc);
  +    return rc;
  +}
  +
  +static int rpmzsfClose(rpmzsf zsf)
  +{
  +    int rc = -2;
  +
  +SPEW("-->\t%s(%p)\n", __FUNCTION__, zsf);
  +    if (ZSF_ISSET(DECOMPRESS)) {     /* decompress */
  +assert(zsf->dstream);
  +    } else {                         /* compress */
  +assert(zsf->cstream);
  +     /* close frame */
  +     zsf->zob.dst  = zsf->ob;
  +     zsf->zob.size = zsf->nob;
  +     zsf->zob.pos  = 0;
  +     /* XXX nremain != 0 on small output buffers. Loop. */
  +     size_t nremain = ZSTD_endStream(zsf->cstream, &zsf->zob);
  +     if (nremain) {
  +fprintf(stderr, "not fully flushed");
  +         rc = -1;
  +     } else {
  +         zsf->nw = fwrite(zsf->ob, 1, zsf->zob.pos, zsf->ofp);
  +assert(zsf->nw == zsf->zob.pos);
  +SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zsf->ob, zsf->zob.pos, 
zsf->ofp, zsf->nw);
  +         rc = 0;
  +     }
  +     rpmzsfFini(zsf);        /* XXX */
  +    }
  +
  +SPEW("<--\t%s(%p) rc %d\n", __FUNCTION__, zsf, rc);
  +    return rc;
  +}
  +
  +/*==============================================================*/
  +static ssize_t rpmzsfRead(rpmzsf zsf, void *b, size_t nb)
  +{
  +    ssize_t rc = 0;
  +
  +SPEW("-->\t%s(%p,%p[%zd])\n", __FUNCTION__, zsf, b, nb);
  +
  +    zsf->zob.dst  = b;
  +    zsf->zob.size = nb;
  +    zsf->zob.pos  = 0;
  +    rc = 0;
  +    while (zsf->zob.pos < zsf->zob.size) {
  +     if (zsf->zib.pos >= zsf->zib.size) {
  +         zsf->nr = fread(zsf->ib, 1, zsf->nib, zsf->ifp);
  +         if (zsf->nr <= 0) {
  +             rc = zsf->nr;
  +             break;
  +         }
  +         zsf->zib.src  = zsf->ib;
  +         zsf->zib.size = zsf->nr;
  +         zsf->zib.pos  = 0;
  +     }
  +     while (zsf->zib.pos < zsf->zib.size) {
  +         zsf->nb = ZSTD_decompressStream(zsf->dstream, &zsf->zob, &zsf->zib);
  +SPEW("\t%s: nb %8zd\tzob %zu:%zu\tzib %zu:%zu\n", __FUNCTION__, zsf->nb, 
zsf->zob.pos, zsf->zob.size, zsf->zib.pos, zsf->zib.size);
  +         /* zsf->nb : size of next compressed block */
  +         if (ZSTD_isError(zsf->nb)) {
  +             fprintf(stderr, "ZSTD_decompressStream() error : %s \n",
  +                             ZSTD_getErrorName(zsf->nb));
  +             rc = -1;
  +             break;
  +         }
  +         if (zsf->zob.pos >= zsf->zob.size)
  +             break;
  +     }
  +    }
  +     rc = (rc >= 0 ? (ssize_t)zsf->zob.pos : rc);
  + 
  +SPEW("<--\t%s(%p,%p[%zd]) rc %ld\n", __FUNCTION__, zsf, b, nb, rc);
  +    return rc;
  +}
  +
  +static ssize_t rpmzsfWrite(rpmzsf zsf, void *b, size_t nb)
  +{
  +    ssize_t rc = -2;
  +
  +SPEW("-->\t%s(%p,%p[%zd])\n", __FUNCTION__, zsf, b, nb);
  +     zsf->zib.src  = b;
  +     zsf->zib.size = nb;
  +     zsf->zib.pos  = 0;
  +     rc = 0;
  +     while (zsf->zib.pos < zsf->zib.size) {
  +
  +         zsf->zob.dst  = zsf->ob;
  +         zsf->zob.size = zsf->nob;
  +         zsf->zob.pos  = 0;
  +
  +         zsf->nb = ZSTD_compressStream(zsf->cstream, &zsf->zob, &zsf->zib);
  +SPEW("\t%s: nb %8zd\tzob %zu:%zu\tzib %zu:%zu\n", "compress", zsf->nb, 
zsf->zob.pos, zsf->zob.size, zsf->zib.pos, zsf->zib.size);
  +         /* zsf->nb is guaranteed to be <= ZSTD_CStreamInSize() */
  +         if (ZSTD_isError(zsf->nb)) {
  +             fprintf(stderr, "ZSTD_compressStream() error : %s \n",
  +                             ZSTD_getErrorName(zsf->nb));
  +             rc = -1;
  +             break;
  +         }
  +
  +         if (zsf->zob.pos > 0) {
  +             zsf->nw = fwrite(zsf->ob, 1, zsf->zob.pos, zsf->ofp);
  +assert(zsf->nw == zsf->zob.pos);
  +SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zsf->ob, zsf->zob.pos, 
zsf->ofp, zsf->nw);
  +         }
  +
  +     }
  +
  +     rc = (zsf->zib.pos == zsf->zib.size ? (ssize_t) zsf->zib.pos : -1);
  +
  +SPEW("<--\t%s(%p,%p[%zd]) rc %ld\n", __FUNCTION__, zsf, b, nb, rc);
  +    return rc;
  +}
  +
  +static int rpmzsfSeek(void * _zsf, _libio_pos_t pos, int whence)
  +{
  +    int rc = -2;
  +    return rc;
  +}
  +
  +static rpmzsf rpmzsfOpen(const char * path, const char * fmode, int fdno, 
unsigned flags)
  +{
  +    return  rpmzsfNew(path, fmode, fdno, flags);
  +}
  +
  +static rpmzsf rpmzsfFdopen(void * _fdno, const char * fmode)
  +{
  +#ifdef       NOTYET
  +    int fdno = (int)((long)_fdno);   /* XXX hack */
  +    return  rpmzsfNew(NULL, fmode, fdno, 0);
  +#else
  +    return NULL;
  +#endif
  +}
  +
  +/*==============================================================*/
  +static ssize_t rpmzsfCopyAll(rpmzsf zsf)
  +{
  +    ssize_t rc = -2;
  +
  +SPEW("==> %s(%p) oflags 0x%x\n", __FUNCTION__, zsf, zsf->oflags);
  +
  +    if (ZSF_ISSET(DECOMPRESS)) {     /* decompress */
  +assert(zsf->dstream);
  +SPEW("\tDecompressing ... eof %d\n", feof(zsf->ifp));
  +     do {
  +         zsf->nr = rpmzsfRead(zsf, zsf->ob, zsf->nob);
  +         if (zsf->nr <= 0) {
  +             rc = zsf->nr;
  +             break;
  +         }
  +         zsf->nw = fwrite(zsf->ob, 1, zsf->nr, zsf->ofp);
  +assert(zsf->nw == zsf->nr);
  +SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zsf->ob, zsf->nr, zsf->ofp, 
zsf->nw);
  +         if (zsf->nw <= 0) {
  +             rc = zsf->nw;
  +             break;
  +         }
  +     } while (zsf->zib.pos < zsf->zib.size);
  +    } else {                         /* compress */
  +assert(zsf->cstream);
  +SPEW("\tCompressing ... eof %d\n", feof(zsf->ifp));
  +     rc = 0;
  +     while (!feof(zsf->ifp)) {
  +         zsf->nr = fread(zsf->ib, 1, zsf->nib, zsf->ifp);
  +SPEW("<--\tfread(%p, 1, %zu, %p) nr %zd eof %d\n", zsf->ib, zsf->nib, 
zsf->ifp, zsf->nr, feof(zsf->ifp));
  +         if (zsf->nr <= 0) {
  +             rc = zsf->nr;
  +             break;
  +         }
  +         zsf->nw = rpmzsfWrite(zsf, zsf->ib, zsf->nr);
  +         if (zsf->nw <= 0) {
  +             rc = zsf->nw;
  +             break;
  +         }
  +     }
  +     if (!rc)
  +         rc = rpmzsfClose(zsf);
  +    }
  +
  +rpmzsfDump(__FUNCTION__, zsf);
  +SPEW("<== %s(%p) rc %ld\n", __FUNCTION__, zsf, rc);
  +    return rc;
  +}
  +
  +static int compressFile(const char *ifn, const char *fmode)
  +{
  +    rpmzsf zsf = rpmzsfOpen(ifn, fmode, -1, RPMZSF_FLAGS_NONE);
  +    zsf->ifp = fopen(ifn, "rb");;
  +SPEW("<--\tfopen(\"%s\", \"%s\") ifp %p\n", ifn, "rb", zsf->ifp);
  +assert(zsf->ifp);
  +    const char * ofn = rpmGetPath(ifn, ".zst", NULL);
  +    zsf->ofp = fopen(ofn, "wb");;
  +SPEW("<--\tfopen(\"%s\", \"%s\") ofp %p\n", ofn, "wb", zsf->ofp);
  +assert(zsf->ofp);
  +    ofn = _free(ofn);
  +    int rc = rpmzsfCopyAll(zsf);
  +    rc = rpmzsfClose(zsf);           /* XXX elsewhere */
  +    zsf = rpmzsfFree(zsf);
  +    return rc;
  +}
  +
  +static int decompressFile(const char *ifn, const char *fmode)
  +{
  +    rpmzsf zsf = rpmzsfOpen(ifn, fmode, -1, RPMZSF_FLAGS_DECOMPRESS);
  +    zsf->ifp = fopen(ifn, "rb");;
  +SPEW("<--\tfopen(\"%s\", \"%s\") ifp %p\n", ifn, "rb", zsf->ifp);
  +assert(zsf->ifp);
  +    zsf->ofp = stdout;
  +    int rc = rpmzsfCopyAll(zsf);
  +    zsf = rpmzsfFree(zsf);
  +    return rc;
  +}
  +
  +/*==============================================================*/
  +#if !defined(POPT_BIT_XOR)
  +#define      POPT_BIT_XOR    (POPT_ARG_VAL|POPT_ARGFLAG_XOR)
  +#endif
  +
  +static struct poptOption rpmzsfOptionsTable[] = {
  + { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN,       &_debug, 1,
  +     NULL, NULL },
  +
  + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioOflagsPoptTable, 0,
  +     N_("Open(2) flags:"), NULL },
  +
  + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
  +     N_("Common options for all rpmio executables:"), NULL },
  +
  +  POPT_AUTOALIAS
  +  POPT_AUTOHELP
  +  POPT_TABLEEND
  +};
  +
  +int
  +main(int argc, char *argv[])
  +{
  +    poptContext con = rpmioInit(argc, argv, rpmzsfOptionsTable);
  +    ARGV_t av = poptGetArgs(con);
  +    int ac = argvCount(av);
  +    int ec = 0;
  +
  +    if (ac != 1) {
  +     printf("wrong arguments\n");
  +     printf("usage:\n");
  +     printf("%s FILE\n", argv[0]);
  +     return 1;
  +    }
  +    const char * ifn = xstrdup(av[0]);
  +
  +#ifdef       NOTYET
  +    oflags = rpmioOflags;
  +#endif
  +
  +    switch (2) {
  +    case 1:  ec = compressFile(ifn, "w3?.zstio");    break;
  +    case 2:  ec = decompressFile(ifn, "r?.zstio");   break;
  +    }
  +
  +    ifn = _free(ifn);
  +
  +    con = rpmioFini(con);
  +
  +    return ec;
  +}
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/zstio.c
  ============================================================================
  $ cvs diff -u -r1.1.2.1 -r1.1.2.2 zstio.c
  --- rpm/rpmio/zstio.c 30 May 2017 23:48:23 -0000      1.1.2.1
  +++ rpm/rpmio/zstio.c 1 Jun 2017 17:39:56 -0000       1.1.2.2
  @@ -5,8 +5,11 @@
   
   #include "system.h"
   
  +#include <stddef.h>        /* size_t */
  +#include <stdint.h>
  +
   #if  defined(HAVE_STDBOOL_H)
  -#include <stdbool.h>
  +# include <stdbool.h>
   #else
   typedef      enum { true = 1, false = 0 } bool;
   #endif
  @@ -15,8 +18,6 @@
   #include <rpmmacro.h>
   #include <rpmcb.h>
   
  -#if defined(WITH_ZSTD)
  -
   #include <zstd.h>
   
   #include "debug.h"
  @@ -38,8 +39,11 @@
       unsigned char win[RSYNC_WIN];    /* window elements */
   } * rsync_state;
   
  -typedef void * gzFile;       /* XXX */
  +/* Should zstflush be called only after RSYNC_WIN boundaries? */
  +static int enable_rsync = 1;
   
  +/* =============================================================== */
  +typedef      struct gzFile_s *gzFile;
   typedef struct zstdFILE_s {
       gzFile gz;                               /* gzFile is a pointer */
       struct rsync_state_s rs;
  @@ -47,57 +51,66 @@
       uint32_t nb;                     /* bytes pending for sync */
   } * zstdFILE;                        /* like FILE, to use with star */
   
  -
   #ifdef __cplusplus
   GENfree(zstdFILE)
   #endif       /* __cplusplus */
   
  -/* Should zstflush be called only after RSYNC_WIN boundaries? */
  -static int enable_rsync = 1;
  +struct gzFile_s {
  +    FILE *const  ifp;
  +    size_t const nib;
  +    void *const  ib;
  +    FILE *const  ofp;
  +    size_t const nob;
  +    void *const ob;
  +    ZSTD_DStream *const zds;
  +    ZSTD_CStream *const zcs;
  +};
   
   /* =============================================================== */
   static
  -const char * zsferror(gzFile gz, int *errnum)
  +const char * rpmzsfError(gzFile gz, int *errnum)
   {
       return "";
   }
   
   static
  -gzFile zsfopen(const char *path, const char * fmode, int fdno)
  +gzFile rpmzsfOpen(const char *path, const char * fmode, int fdno)
   {
       return NULL;
   }
   
   static
  -int zsfread(gzFile gz, void *buf, unsigned count)
  +int rpmzsfRead(gzFile gz, const void *buf, size_t len)
   {
       int rc = -1;
  +
       return rc;
   }
   
   static
  -int zsfwrite(gzFile gz, const void *buf, unsigned count)
  +int rpmzsfWrite(gzFile gz, void *buf, unsigned len)
   {
       int rc = -1;
  +
       return rc;
   }
   
   static
  -int zsfseek(gzFile gz, off_t offset, int whence)
  +int rpmzsfSeek(gzFile gz, off_t offset, int whence)
   {
       int rc = -1;
       return rc;
   }
   
   static
  -int zsfclose(gzFile gz)
  +int rpmzsfClose(gzFile gz)
   {
       int rc = -1;
       return rc;
   }
   
   static
  -int zsfflush(gzFile gz, int flush)
  +int rpmzsfFlush(gzFile gz)
   {
       int rc = -1;
       return rc;
  @@ -245,20 +258,20 @@
        if (!sync_hint(zsf, buf[i]))
            continue;
        n = i + 1 - (begin - buf);
  -     rc = zsfwrite(zsf->gz, (const char *)begin, (unsigned)n);
  +     rc = rpmzsfWrite(zsf->gz, (void *)begin, (unsigned)n);
        if (rc < 0)
            return (n_written ? n_written : rc);
        n_written += rc;
        if (rc < (ssize_t)n)
            return n_written;
        begin += n;
  -     rc = zsfflush(zsf->gz, 0);
  +     rc = rpmzsfFlush(zsf->gz);
        if (rc < 0)
            return (n_written ? n_written : rc);
       }
       if (begin < buf + len) {
        n = len - (begin - buf);
  -     rc = zsfwrite(zsf->gz, (const char *)begin, (unsigned)n);
  +     rc = rpmzsfWrite(zsf->gz, (void *)begin, (unsigned)n);
        if (rc < 0)
            return (n_written ? n_written : rc);
        n_written += rc;
  @@ -295,7 +308,7 @@
       mode_t mode = (fmode && fmode[0] == 'w' ? O_WRONLY : O_RDONLY);
   
       zsf = (zstdFILE) xcalloc(1, sizeof(*zsf));
  -    zsf->gz = zsfopen(path, fmode, -1);
  +    zsf->gz = rpmzsfOpen(path, fmode, -1);
       if (zsf->gz == NULL) {
        zsf = _free(zsf);
        return NULL;
  @@ -318,7 +331,7 @@
       fdno = fdSetFdno(fd, -1);                /* XXX skip the fdio close */
       if (fdno < 0) return NULL;
       zsf = (zstdFILE) xcalloc(1, sizeof(*zsf));
  -    zsf->gz = zsfopen(NULL, fmode, fdno);
  +    zsf->gz = rpmzsfOpen(NULL, fmode, fdno);
       if (zsf->gz == NULL) {
        zsf = _free(zsf);
        return NULL;
  @@ -335,7 +348,7 @@
       zstdFILE zsf;
       zsf = (zstdFILE) zstFileno(fd);
       if (zsf == NULL) return -2;
  -    return zsfflush(zsf->gz, 0);
  +    return rpmzsfFlush(zsf->gz);
   }
   
   /* =============================================================== */
  @@ -351,11 +364,11 @@
       if (zsf == NULL) return -2;      /* XXX can't happen */
   
       fdstat_enter(fd, FDSTAT_READ);
  -    rc = zsfread(zsf->gz, buf, (unsigned)count);
  +    rc = rpmzsfRead(zsf->gz, buf, (unsigned)count);
   DBGIO(fd, (stderr, "==>\tzstRead(%p,%p,%u) rc %lx %s\n", cookie, buf, 
(unsigned)count, (unsigned long)rc, fdbg(fd)));
       if (rc < 0) {
        int zerror = 0;
  -     fd->errcookie = zsferror(zsf->gz, &zerror);
  +     fd->errcookie = rpmzsfError(zsf->gz, &zerror);
   #ifdef       DYING
        if (zerror == Z_ERRNO) {
            fd->syserrno = errno;
  @@ -386,11 +399,11 @@
       if (enable_rsync)
        rc = rsyncable_write(zsf, (const unsigned char *)buf, (unsigned)count);
       else
  -     rc = zsfwrite(zsf->gz, (void *)buf, (unsigned)count);
  +     rc = rpmzsfWrite(zsf->gz, (void *)buf, (unsigned)count);
   DBGIO(fd, (stderr, "==>\tzstWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, 
(unsigned)count, (unsigned long)rc, fdbg(fd)));
       if (rc < (ssize_t)count) {
        int zerror = 0;
  -     fd->errcookie = zsferror(zsf->gz, &zerror);
  +     fd->errcookie = rpmzsfError(zsf->gz, &zerror);
   #ifdef       DYING
        if (zerror == Z_ERRNO) {
            fd->syserrno = errno;
  @@ -421,11 +434,11 @@
       if (zsf == NULL) return -2;      /* XXX can't happen */
   
       fdstat_enter(fd, FDSTAT_SEEK);
  -    rc = zsfseek(zsf->gz, (long)p, whence);
  +    rc = rpmzsfSeek(zsf->gz, (long)p, whence);
   DBGIO(fd, (stderr, "==>\tzstSeek(%p,%ld,%d) rc %lx %s\n", cookie, (long)p, 
whence, (unsigned long)rc, fdbg(fd)));
       if (rc < 0) {
        int zerror = 0;
  -     fd->errcookie = zsferror(zsf->gz, &zerror);
  +     fd->errcookie = rpmzsfError(zsf->gz, &zerror);
   #ifdef       DYING
        if (zerror == Z_ERRNO) {
            fd->syserrno = errno;
  @@ -448,7 +461,7 @@
       if (zsf == NULL) return -2;      /* XXX can't happen */
   
       fdstat_enter(fd, FDSTAT_CLOSE);
  -    rc = zsfclose(zsf->gz);
  +    rc = rpmzsfClose(zsf->gz);
       zsf->gz = NULL;
       zsf = _free(zsf);
   
  @@ -483,4 +496,3 @@
   
   FDIO_t zstio = &zstio_s;
   
  -#endif       /* WITH_ZLIB */
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to