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

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  [email protected]
  Module: rpm                              Date:   01-Jun-2017 23:10:29
  Branch: rpm-5_4                          Handle: 2017060121102801

  Added files:              (Branch: rpm-5_4)
    rpm/rpmio               rpmzstd.h
  Modified files:           (Branch: rpm-5_4)
    rpm                     CHANGES
    rpm/rpmio               Makefile.am librpmio.vers macro.c rpmio.c tzstd.c
                            zstdio.c

  Log:
    - zstd: rearrange the code into final form.

  Summary:
    Revision    Changes     Path
    1.3501.2.569+1  -0      rpm/CHANGES
    1.293.2.86  +1  -1      rpm/rpmio/Makefile.am
    2.199.2.85  +1  -0      rpm/rpmio/librpmio.vers
    2.249.2.48  +4  -0      rpm/rpmio/macro.c
    1.230.2.56  +0  -2      rpm/rpmio/rpmio.c
    1.1.2.1     +111 -0     rpm/rpmio/rpmzstd.h
    1.1.2.3     +9  -493    rpm/rpmio/tzstd.c
    1.1.2.2     +505 -26    rpm/rpmio/zstdio.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/CHANGES
  ============================================================================
  $ cvs diff -u -r1.3501.2.568 -r1.3501.2.569 CHANGES
  --- rpm/CHANGES       1 Jun 2017 18:38:24 -0000       1.3501.2.568
  +++ rpm/CHANGES       1 Jun 2017 21:10:28 -0000       1.3501.2.569
  @@ -1,4 +1,5 @@
   5.4.17 -> 5.4.18:
  +    - jbj: zstd: rearrange the code into final form.
       - jbj: zstd: fix: rename from "zstio" to "zstdio".
       - jbj: zstd: stub in zstd compression framework.
       - jbj: msqio: abstract out the AIO queue (AIOQ_t for now).
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/Makefile.am
  ============================================================================
  $ cvs diff -u -r1.293.2.85 -r1.293.2.86 Makefile.am
  --- rpm/rpmio/Makefile.am     1 Jun 2017 18:38:25 -0000       1.293.2.85
  +++ rpm/rpmio/Makefile.am     1 Jun 2017 21:10:29 -0000       1.293.2.86
  @@ -161,7 +161,7 @@
        rpmmqtt.h rpmmrb.h rpmmsq.h rpmnix.h rpmnss.h \
        rpmodbc.h rpmperl.h rpmpgp.h rpmpython.h rpmruby.h rpmsed.h rpmsm.h 
rpmsp.h \
        rpmsq.h rpmsql.h rpmsquirrel.h rpmssl.h rpmsvn.h rpmsx.h rpmsyck.h \
  -     rpmtcl.h rpmtpm.h rpmuuid.h rpmxar.h rpmz.h rpmzq.h \
  +     rpmtcl.h rpmtpm.h rpmuuid.h rpmxar.h rpmz.h rpmzstd.h rpmzq.h \
        set.h tar.h ugid.h rpmio-stub.h
   
   usrlibdir = $(libdir)
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/librpmio.vers
  ============================================================================
  $ cvs diff -u -r2.199.2.84 -r2.199.2.85 librpmio.vers
  --- rpm/rpmio/librpmio.vers   1 Jun 2017 18:38:25 -0000       2.199.2.84
  +++ rpm/rpmio/librpmio.vers   1 Jun 2017 21:10:29 -0000       2.199.2.85
  @@ -1029,6 +1029,7 @@
       _rpmzstdPool;
       zstdio;
       rpmzstdClose;
  +    rpmzstdDump;
       rpmzstdFdopen;
       rpmzstdFlush;
       rpmzstdNew;
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/macro.c
  ============================================================================
  $ cvs diff -u -r2.249.2.47 -r2.249.2.48 macro.c
  --- rpm/rpmio/macro.c 30 May 2017 19:18:38 -0000      2.249.2.47
  +++ rpm/rpmio/macro.c 1 Jun 2017 21:10:29 -0000       2.249.2.48
  @@ -3490,6 +3490,10 @@
        &&      magic[2] == 'Z' && magic[3] == 'O')     /* lzop */
        *compressed = COMPRESSED_LZOP;
       else
  +    if (magic[0] == (unsigned char) 0x28 && magic[1] == 0xB5
  +     &&      magic[2] == 0x2F)               /* zstd (magic[3] is a version) 
*/
  +     *compressed = COMPRESSED_ZSTD;
  +    else
   #if !defined(RPM_VENDOR_OPENPKG) && !defined(RPM_VENDOR_FEDORA) && 
!defined(RPM_VENDOR_MANDRIVA) /* extension-based-compression-detection */
       /* XXX Ick, LZMA has no magic. See http://lkml.org/lkml/2005/6/13/285 */
       if (magic[ 9] == (unsigned char) 0x00 && magic[10] == (unsigned char) 
0x00 &&
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmio.c
  ============================================================================
  $ cvs diff -u -r1.230.2.55 -r1.230.2.56 rpmio.c
  --- rpm/rpmio/rpmio.c 1 Jun 2017 18:38:25 -0000       1.230.2.55
  +++ rpm/rpmio/rpmio.c 1 Jun 2017 21:10:29 -0000       1.230.2.56
  @@ -3798,9 +3798,7 @@
   
       RPMIOPOOL_FREE(aio)
       RPMIOPOOL_FREE(msq)
  -#ifdef       NOTYET
       RPMIOPOOL_FREE(zstd)
  -#endif
   
       RPMIOPOOL_FREE(html)
       RPMIOPOOL_FREE(mire)
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmzstd.h
  ============================================================================
  $ cvs diff -u -r0 -r1.1.2.1 rpmzstd.h
  --- /dev/null 2017-06-01 23:06:28.000000000 +0200
  +++ rpmzstd.h 2017-06-01 23:10:29.487568940 +0200
  @@ -0,0 +1,111 @@
  +#ifndef      _H_RPMZSTD_
  +#define      _H_RPMZSTD_
  +
  +/**
  + */
  +extern int _rpmzstd_debug;
  +
  +typedef      struct rpmzstd_s * rpmzstd;
  +
  +/**
  + */
  +#define _KFB(n) (1U << (n))
  +#define _MFB(n) (_KFB(n))
  +typedef enum rpmzstdFlags_e {
  +    RPMZSTD_FLAGS_NONE               = 0,
  +     /* bits 0-7 reserved */
  +    RPMZSTD_FLAGS_DEBUG              = _MFB( 8),
  +    RPMZSTD_FLAGS_DECOMPRESS = _MFB( 9),
  +     /* bits 10-31 unused */
  +} rpmzstdFlags;
  +#undef  _MFB
  +#undef  _KFB
  +
  +#ifdef __cplusplus
  +extern "C" {
  +#endif
  +
  +/**
  + */
  +#if defined(_RPMZSTD_INTERNAL)
  +struct rpmzstd_s {
  +    struct rpmioItem_s _item;        /*!< usage mutex and pool identifier. */
  +    const char * path;               /*!> open path. */
  +    const char * fmode;
  +    rpmzstdFlags flags;
  +    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;
  +};
  +
  +#ifdef       NOTYET
  +int rpmzstdSeek(void * _zstd, _libio_pos_t pos, int whence)
  +#endif
  +rpmzstd rpmzstdOpen(const char * path, const char * fmode, int fdno, 
unsigned flags);
  +rpmzstd rpmzstdFdopen(void * _fdno, const char * fmode);
  +int rpmzstdDump(const char *msg, void * _zstd, FILE *fp);
  +
  +#endif       /* _RPMZSTD_INTERNAL */
  +
  +/**
  + * Unreference a zstd wrapper instance.
  + * @param zstd               zstd wrapper
  + * @return           NULL on last dereference
  + */
  +rpmzstd rpmzstdUnlink (rpmzstd zstd);
  +#define      rpmzstdUnlink(_zstd)    \
  +    ((rpmzstd)rpmioUnlinkPoolItem((rpmioItem)(_zstd), __FUNCTION__, 
__FILE__, __LINE__))
  +
  +/**
  + * Reference a zstd wrapper instance.
  + * @param zstd               zstd wrapper
  + * @return           new zstd wrapper reference
  + */
  +rpmzstd rpmzstdLink (rpmzstd zstd);
  +#define      rpmzstdLink(_zstd)      \
  +    ((rpmzstd)rpmioLinkPoolItem((rpmioItem)(_zstd), __FUNCTION__, __FILE__, 
__LINE__))
  +
  +/**
  + * Destroy a zstd wrapper.
  + * @param zstd               zstd wrapper
  + * @return           NULL on last dereference
  + */
  +rpmzstd rpmzstdFree(rpmzstd zstd);
  +#define      rpmzstdFree(_zstd)      \
  +    ((rpmzstd)rpmioFreePoolItem((rpmioItem)(_zstd), __FUNCTION__, __FILE__, 
__LINE__))
  +
  +/**
  + * Create a zstd wrapper.
  + * @return           zstd wrapper
  + */
  +rpmzstd rpmzstdNew(const char * path, const char * fmode, int fdno, unsigned 
flags);
  +
  +ssize_t rpmzstdRead(rpmzstd zstd, void * b, size_t nb);
  +
  +ssize_t rpmzstdWrite(rpmzstd zstd, const void * b, size_t nb);
  +
  +int rpmzstdFlush(void * _zstd);
  +
  +int rpmzstdClose(rpmzstd zstd);
  +
  +#ifdef __cplusplus
  +}
  +#endif
  +
  +#endif       /* _H_RPMZSTD_ */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/tzstd.c
  ============================================================================
  $ cvs diff -u -r1.1.2.2 -r1.1.2.3 tzstd.c
  --- rpm/rpmio/tzstd.c 1 Jun 2017 18:38:25 -0000       1.1.2.2
  +++ rpm/rpmio/tzstd.c 1 Jun 2017 21:10:29 -0000       1.1.2.3
  @@ -20,502 +20,18 @@
   #include <zstd.h>            // presumes zstd library is installed
   #endif
   
  -#include "debug.h"
  +#define      _RPMZSTD_INTERNAL
  +#include "rpmzstd.h"
   
  -static int _debug;
  +#include "debug.h"
   
  -int _rpmzstd_debug = -1;
  +#define      ZSTDF_ISSET(_foo)               (zstd->flags & 
RPMZSTD_FLAGS_##_foo)
   
   #define SPEW(_fmt, ...) \
  -    if ((zstd && ZSTD_ISSET(DEBUG)) || _rpmzstd_debug || _rpmio_debug) \
  +    if ((zstd && ZSTDF_ISSET(DEBUG)) || _rpmzstd_debug || _rpmio_debug) \
        fprintf(stderr, _fmt, __VA_ARGS__)
   
  -#undef       COMPRESSOR
  -
  -typedef      struct rpmzstd_s * rpmzstd;
  -struct rpmzstd_s {
  -    struct rpmioItem_s _item;        /*!< usage mutex and pool identifier. */
  -    const char * path;               /*!> open path. */
  -    const char * fmode;
  -    unsigned flags;
  -#define      RPMZSTD_FLAGS_NONE              (0)
  -#define      RPMZSTD_FLAGS_DEBUG             (1<<0)
  -#define      RPMZSTD_FLAGS_DECOMPRESS                (1<<1)
  -#define      ZSTD_ISSET(_foo)                (zstd->flags & 
RPMZSTD_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 rpmzstdDump(const char * msg, rpmzstd zstd)
  -{
  -    if (msg) fprintf(stderr, "========================== %s\n", msg);
  -    if (zstd) {
  -#define PRINT(_fmt, _foo) \
  -    {   fprintf(stderr, "%25s: %"#_fmt"\n", #_foo, zstd->_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 (zstd->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 (zstd->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 rpmzstdLink(_zstd)   \
  -    ((rpmzstd)rpmioLinkPoolItem((rpmioItem)(_zstd), __FUNCTION__, __FILE__, 
__LINE__))
  -
  -#define rpmzstdFree(_zstd)   \
  -    ((rpmzstd)rpmioFreePoolItem((rpmioItem)(_zstd), __FUNCTION__, __FILE__, 
__LINE__))
  -/* =============================================================== */
  -static char * rpmzstdDbug(void *_zstd, char *b, size_t nb)
  -{
  -    rpmzstd zstd = (rpmzstd) _zstd;
  -    size_t len = strlen(b);
  -    char * be = b + len;
  -    rpmioItem item = (rpmioItem) zstd;
  -    long use;
  -
  -    if (zstd && (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, "========================== zstd(%p) use %ld\n",
  -             zstd, use);
  -#define PRINT(_fmt, _foo) \
  -    {        be += sprintf(be, "%25s: %"#_fmt"\n", #_foo, zstd->_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 (zstd->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 (zstd->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 rpmzstdInit(void *_zstd)
  -{
  -}
  -
  -
  -static void rpmzstdFini(void *_zstd)
  -{
  -    rpmzstd zstd = (rpmzstd) _zstd;
  -    if (zstd) {
  -     if (zstd->path)
  -         zstd->path = _free(zstd->path);
  -     if (zstd->fmode)
  -         zstd->fmode = _free(zstd->fmode);
  -     zstd->flags = 0;
  -     zstd->fdno = -1;
  -     zstd->oflags = 0;
  -     zstd->omode = 0;
  -
  -     zstd->nb = 0;
  -     zstd->nr = 0;
  -     zstd->nw = 0;
  -     zstd->level = 0;
  -
  -     if (zstd->ifp && fileno(zstd->ifp) > 2)
  -         fclose(zstd->ifp);
  -     zstd->ifp = NULL;
  -     if (zstd->ib)
  -         zstd->ib = _free(zstd->ib);
  -     zstd->nib = 0;
  -
  -     if (zstd->ofp && fileno(zstd->ofp) > 2)
  -         fclose(zstd->ofp);
  -     zstd->ofp = NULL;
  -     if (zstd->ob)
  -         zstd->ob = _free(zstd->ob);
  -     zstd->nob = 0;
  -
  -     if (zstd->cstream)
  -         ZSTD_freeCStream(zstd->cstream);
  -     zstd->cstream = NULL;
  -     if (zstd->dstream)
  -         ZSTD_freeDStream(zstd->dstream);
  -     zstd->dstream = NULL;
  -
  -     zstd->zib.src = NULL;
  -     zstd->zib.pos = 0;
  -     zstd->zib.size = 0;
  -     zstd->zob.dst = NULL;
  -     zstd->zob.pos = 0;
  -     zstd->zob.size = 0;
  -    }
  -}
  -
  -RPMIOPOOL_MODULE(zstd)
  -
  -rpmzstd rpmzstdNew(const char *path, const char *fmode, int fdno, unsigned 
flags)
  -{
  -    rpmzstd zstd = rpmzstdGetPool(_rpmzstdPool);
  -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 |= RPMZSTD_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;
  -    }
  -
  -    zstd->path = xstrdup(path);
  -    zstd->fmode = xstrdup(fmode);
  -    zstd->fdno = fdno;
  -    zstd->flags = flags;
  -
  -    zstd->oflags = oflags;
  -    zstd->omode = omode;
  -
  -    zstd->level = level;
  -
  -    if (ZSTD_ISSET(DECOMPRESS)) {    /* decompress */
  -     zstd->dstream = ZSTD_createDStream();
  -     if (zstd->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.
  -      */
  -     zstd->nb = ZSTD_initDStream(zstd->dstream);
  -     if (ZSTD_isError(zstd->nb)) {
  -         fprintf(stderr, "ZSTD_initDStream() error : %s \n",
  -             ZSTD_getErrorName(zstd->nb));
  -         exit(11);   /* XXX */
  -     }
  -     zstd->nib = ZSTD_CStreamInSize();
  -     zstd->ib = xmalloc(zstd->nib);
  -#ifdef       NOTYET
  -     zstd->nob = BUFSIZ;
  -     zstd->ob = xmalloc(zstd->nob);
  -#else
  -     zstd->nob = ZSTD_CStreamOutSize();
  -     zstd->ob = xmalloc(zstd->nob);
  -#endif
  -    } else {                         /* compress */
  -     zstd->cstream = ZSTD_createCStream();
  -     if (zstd->cstream == NULL) {
  -         fprintf(stderr, "ZSTD_createCStream() error \n");
  -         exit(10);
  -     }
  -     zstd->nb = ZSTD_initCStream(zstd->cstream, level);
  -     if (ZSTD_isError(zstd->nb)) {
  -         fprintf(stderr, "ZSTD_initCStream() error : %s \n",
  -             ZSTD_getErrorName(zstd->nb));
  -         exit(11);   /* XXX */
  -     }
  -#ifdef       NOTYET
  -     zstd->nib = BUFSIZ;
  -     zstd->ib = xmalloc(zstd->nib);
  -#else
  -     zstd->nib = ZSTD_CStreamInSize();
  -     zstd->ib = xmalloc(zstd->nib);
  -#endif
  -     zstd->nob = ZSTD_CStreamOutSize();
  -     zstd->ob = xmalloc(zstd->nob);
  -    }
  -
  -    return rpmzstdLink(zstd);
  -}
  -
  -int rpmzstdFlush(rpmzstd zstd)
  -{
  -    int rc = -2;
  -
  -    if (ZSTD_ISSET(DECOMPRESS)) {    /* decompress */
  -assert(zstd->dstream);
  -    } else {                         /* compress */
  -assert(zstd->cstream);
  -     /* close frame */
  -     zstd->zob.dst  = zstd->ob;
  -     zstd->zob.size = zstd->nob;
  -     zstd->zob.pos  = 0;
  -     /* XXX nremain != 0 on small output buffers. Loop. */
  -     size_t nremain = ZSTD_flushStream(zstd->cstream, &zstd->zob);
  -     if (nremain) {
  -fprintf(stderr, "not fully flushed");
  -         rc = -1;
  -     } else {
  -         zstd->nw = fwrite(zstd->ob, 1, zstd->zob.pos, zstd->ofp);
  -assert(zstd->nw == zstd->zob.pos);
  -SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zstd->ob, zstd->zob.pos, 
zstd->ofp, zstd->nw);
  -         rc = 0;
  -     }
  -    }
  -
  -SPEW("<--\t%s(%p) rc %d\n", __FUNCTION__, zstd, rc);
  -    return rc;
  -}
  -
  -int rpmzstdClose(rpmzstd zstd)
  -{
  -    int rc = -2;
  -
  -SPEW("-->\t%s(%p)\n", __FUNCTION__, zstd);
  -    if (ZSTD_ISSET(DECOMPRESS)) {    /* decompress */
  -assert(zstd->dstream);
  -    } else {                         /* compress */
  -assert(zstd->cstream);
  -     /* close frame */
  -     zstd->zob.dst  = zstd->ob;
  -     zstd->zob.size = zstd->nob;
  -     zstd->zob.pos  = 0;
  -     /* XXX nremain != 0 on small output buffers. Loop. */
  -     size_t nremain = ZSTD_endStream(zstd->cstream, &zstd->zob);
  -     if (nremain) {
  -fprintf(stderr, "not fully flushed");
  -         rc = -1;
  -     } else {
  -         zstd->nw = fwrite(zstd->ob, 1, zstd->zob.pos, zstd->ofp);
  -assert(zstd->nw == zstd->zob.pos);
  -SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zstd->ob, zstd->zob.pos, 
zstd->ofp, zstd->nw);
  -         rc = 0;
  -     }
  -     rpmzstdFini(zstd);      /* XXX */
  -    }
  -
  -SPEW("<--\t%s(%p) rc %d\n", __FUNCTION__, zstd, rc);
  -    return rc;
  -}
  -
  -/*==============================================================*/
  -ssize_t rpmzstdRead(rpmzstd zstd, void *b, size_t nb)
  -{
  -    ssize_t rc = 0;
  -
  -SPEW("-->\t%s(%p,%p[%zd])\n", __FUNCTION__, zstd, b, nb);
  -
  -    zstd->zob.dst  = b;
  -    zstd->zob.size = nb;
  -    zstd->zob.pos  = 0;
  -    rc = 0;
  -    while (zstd->zob.pos < zstd->zob.size) {
  -     if (zstd->zib.pos >= zstd->zib.size) {
  -         zstd->nr = fread(zstd->ib, 1, zstd->nib, zstd->ifp);
  -         if (zstd->nr <= 0) {
  -             rc = zstd->nr;
  -             break;
  -         }
  -         zstd->zib.src  = zstd->ib;
  -         zstd->zib.size = zstd->nr;
  -         zstd->zib.pos  = 0;
  -     }
  -     while (zstd->zib.pos < zstd->zib.size) {
  -         zstd->nb = ZSTD_decompressStream(zstd->dstream, &zstd->zob, 
&zstd->zib);
  -SPEW("\t%s: nb %8zd\tzob %zu:%zu\tzib %zu:%zu\n", __FUNCTION__, zstd->nb, 
zstd->zob.pos, zstd->zob.size, zstd->zib.pos, zstd->zib.size);
  -         /* zstd->nb : size of next compressed block */
  -         if (ZSTD_isError(zstd->nb)) {
  -             fprintf(stderr, "ZSTD_decompressStream() error : %s \n",
  -                             ZSTD_getErrorName(zstd->nb));
  -             rc = -1;
  -             break;
  -         }
  -         if (zstd->zob.pos >= zstd->zob.size)
  -             break;
  -     }
  -    }
  -     rc = (rc >= 0 ? (ssize_t)zstd->zob.pos : rc);
  - 
  -SPEW("<--\t%s(%p,%p[%zd]) rc %ld\n", __FUNCTION__, zstd, b, nb, rc);
  -    return rc;
  -}
  -
  -ssize_t rpmzstdWrite(rpmzstd zstd, void *b, size_t nb)
  -{
  -    ssize_t rc = -2;
  -
  -SPEW("-->\t%s(%p,%p[%zd])\n", __FUNCTION__, zstd, b, nb);
  -     zstd->zib.src  = b;
  -     zstd->zib.size = nb;
  -     zstd->zib.pos  = 0;
  -     rc = 0;
  -     while (zstd->zib.pos < zstd->zib.size) {
  -
  -         zstd->zob.dst  = zstd->ob;
  -         zstd->zob.size = zstd->nob;
  -         zstd->zob.pos  = 0;
  -
  -         zstd->nb = ZSTD_compressStream(zstd->cstream, &zstd->zob, 
&zstd->zib);
  -SPEW("\t%s: nb %8zd\tzob %zu:%zu\tzib %zu:%zu\n", "compress", zstd->nb, 
zstd->zob.pos, zstd->zob.size, zstd->zib.pos, zstd->zib.size);
  -         /* zstd->nb is guaranteed to be <= ZSTD_CStreamInSize() */
  -         if (ZSTD_isError(zstd->nb)) {
  -             fprintf(stderr, "ZSTD_compressStream() error : %s \n",
  -                             ZSTD_getErrorName(zstd->nb));
  -             rc = -1;
  -             break;
  -         }
  -
  -         if (zstd->zob.pos > 0) {
  -             zstd->nw = fwrite(zstd->ob, 1, zstd->zob.pos, zstd->ofp);
  -assert(zstd->nw == zstd->zob.pos);
  -SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zstd->ob, zstd->zob.pos, 
zstd->ofp, zstd->nw);
  -         }
  -
  -     }
  -
  -     rc = (zstd->zib.pos == zstd->zib.size ? (ssize_t) zstd->zib.pos : -1);
  -
  -SPEW("<--\t%s(%p,%p[%zd]) rc %ld\n", __FUNCTION__, zstd, b, nb, rc);
  -    return rc;
  -}
  -
  -int rpmzstdSeek(void * _zstd, _libio_pos_t pos, int whence)
  -{
  -    int rc = -2;
  -    return rc;
  -}
  -
  -rpmzstd rpmzstdOpen(const char * path, const char * fmode, int fdno, 
unsigned flags)
  -{
  -    return  rpmzstdNew(path, fmode, fdno, flags);
  -}
  -
  -rpmzstd rpmzstdFdopen(void * _fdno, const char * fmode)
  -{
  -#ifdef       NOTYET
  -    int fdno = (int)((long)_fdno);   /* XXX hack */
  -    return  rpmzstdNew(NULL, fmode, fdno, 0);
  -#else
  -    return NULL;
  -#endif
  -}
  +#define      COMPRESSOR
   
   /*==============================================================*/
   static ssize_t rpmzstdCopyAll(rpmzstd zstd)
  @@ -524,7 +40,7 @@
   
   SPEW("==> %s(%p) oflags 0x%x\n", __FUNCTION__, zstd, zstd->oflags);
   
  -    if (ZSTD_ISSET(DECOMPRESS)) {    /* decompress */
  +    if (ZSTDF_ISSET(DECOMPRESS)) {   /* decompress */
   assert(zstd->dstream);
   SPEW("\tDecompressing ... eof %d\n", feof(zstd->ifp));
        do {
  @@ -562,7 +78,7 @@
            rc = rpmzstdClose(zstd);
       }
   
  -rpmzstdDump(__FUNCTION__, zstd);
  +rpmzstdDump(__FUNCTION__, zstd, NULL);
   SPEW("<== %s(%p) rc %ld\n", __FUNCTION__, zstd, rc);
       return rc;
   }
  @@ -602,7 +118,7 @@
   #endif
   
   static struct poptOption rpmzstdOptionsTable[] = {
  - { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN,       &_debug, 1,
  + { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN,       
&_rpmzstd_debug, 1,
        NULL, NULL },
   
    { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioOflagsPoptTable, 0,
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/zstdio.c
  ============================================================================
  $ cvs diff -u -r1.1.2.1 -r1.1.2.2 zstdio.c
  --- rpm/rpmio/zstdio.c        1 Jun 2017 18:38:25 -0000       1.1.2.1
  +++ rpm/rpmio/zstdio.c        1 Jun 2017 21:10:29 -0000       1.1.2.2
  @@ -17,12 +17,27 @@
   #include "rpmio_internal.h"
   #include <rpmmacro.h>
   #include <rpmcb.h>
  +#include <yarn.h>
  +#define PEEK(_bolt)  yarnPeekLock(_bolt)
   
  +#if defined(WITH_ZSTD)
   #include <zstd.h>
  +#endif
  +
  +#define      _RPMZSTD_INTERNAL
  +#include "rpmzstd.h"
   
   #include "debug.h"
   
  -#define      ZSTONLY(fd)     assert(fdGetIo(fd) == zstdio)
  +int _rpmzstd_debug = -1;
  +
  +#define      ZSTDF_ISSET(_foo)               (zstd->flags & 
RPMZSTD_FLAGS_##_foo)
  +
  +#define SPEW(_fmt, ...) \
  +    if ((zstd && ZSTDF_ISSET(DEBUG)) || _rpmzstd_debug || _rpmio_debug) \
  +     fprintf(stderr, _fmt, __VA_ARGS__)
  +
  +#define      ZSTDONLY(fd)    assert(fdGetIo(fd) == zstdio)
   
   typedef struct cpio_state_s {
       uint32_t n;                              /* byte progress in cpio header 
*/
  @@ -43,13 +58,13 @@
   static int enable_rsync = 1;
   
   /* =============================================================== */
  -typedef      struct gzFile_s *gzFile;
  +typedef      struct zstdFILE_s *gzFile;
   typedef struct zstdFILE_s {
  -    gzFile gz;                               /* gzFile is a pointer */
  +    rpmzstd zstd;                    /* zstd is a pointer */
       struct rsync_state_s rs;
       struct cpio_state_s cs;
       uint32_t nb;                     /* bytes pending for sync */
  -} * zstdFILE;                        /* like FILE, to use with star */
  +} * zstdFILE;                                /* like FILE, to use with star 
*/
   
   #ifdef __cplusplus
   GENfree(zstdFILE)
  @@ -67,6 +82,475 @@
   };
   
   /* =============================================================== */
  +int rpmzstdDump(const char * msg, void * _zstd, FILE *fp)
  +{
  +    rpmzstd zstd = (rpmzstd) _zstd;
  +    int rc = 0;
  +
  +    if (fp == NULL)  fp = stderr;
  +    if (msg) fprintf(fp, "========================== %s\n", msg);
  +    if (zstd) {
  +#define PRINT(_fmt, _foo) \
  +    {   fprintf(fp, "%25s: %"#_fmt"\n", #_foo, zstd->_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 (zstd->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 (zstd->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
  +
  +    }
  +    return rc;
  +}
  +
  +/* =============================================================== */
  +static char * rpmzstdDbug(void *_zstd, char *b, size_t nb)
  +{
  +    rpmzstd zstd = (rpmzstd) _zstd;
  +    size_t len = strlen(b);
  +    char * be = b + len;
  +    rpmioItem item = (rpmioItem) zstd;
  +    long use;
  +
  +    if (zstd && (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, "========================== zstd(%p) use %ld\n",
  +             zstd, use);
  +#define PRINT(_fmt, _foo) \
  +    {        be += sprintf(be, "%25s: %"#_fmt"\n", #_foo, zstd->_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 (zstd->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 (zstd->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 rpmzstdInit(void *_zstd)
  +{
  +}
  +
  +
  +static void rpmzstdFini(void *_zstd)
  +{
  +    rpmzstd zstd = (rpmzstd) _zstd;
  +    if (zstd) {
  +     if (zstd->path)
  +         zstd->path = _free(zstd->path);
  +     if (zstd->fmode)
  +         zstd->fmode = _free(zstd->fmode);
  +     zstd->flags = 0;
  +     zstd->fdno = -1;
  +     zstd->oflags = 0;
  +     zstd->omode = 0;
  +
  +     zstd->nb = 0;
  +     zstd->nr = 0;
  +     zstd->nw = 0;
  +     zstd->level = 0;
  +
  +     if (zstd->ifp && fileno(zstd->ifp) > 2)
  +         fclose(zstd->ifp);
  +     zstd->ifp = NULL;
  +     if (zstd->ib)
  +         zstd->ib = _free(zstd->ib);
  +     zstd->nib = 0;
  +
  +     if (zstd->ofp && fileno(zstd->ofp) > 2)
  +         fclose(zstd->ofp);
  +     zstd->ofp = NULL;
  +     if (zstd->ob)
  +         zstd->ob = _free(zstd->ob);
  +     zstd->nob = 0;
  +
  +     if (zstd->cstream)
  +         ZSTD_freeCStream(zstd->cstream);
  +     zstd->cstream = NULL;
  +     if (zstd->dstream)
  +         ZSTD_freeDStream(zstd->dstream);
  +     zstd->dstream = NULL;
  +
  +     zstd->zib.src = NULL;
  +     zstd->zib.pos = 0;
  +     zstd->zib.size = 0;
  +     zstd->zob.dst = NULL;
  +     zstd->zob.pos = 0;
  +     zstd->zob.size = 0;
  +    }
  +}
  +
  +RPMIOPOOL_MODULE(zstd)
  +
  +rpmzstd rpmzstdNew(const char *path, const char *fmode, int fdno, unsigned 
flags)
  +{
  +    rpmzstd zstd = rpmzstdGetPool(_rpmzstdPool);
  +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 |= RPMZSTD_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;
  +    }
  +
  +    zstd->path = xstrdup(path);
  +    zstd->fmode = xstrdup(fmode);
  +    zstd->fdno = fdno;
  +    zstd->flags = flags;
  +
  +    zstd->oflags = oflags;
  +    zstd->omode = omode;
  +
  +    zstd->level = level;
  +
  +    if (ZSTDF_ISSET(DECOMPRESS)) {   /* decompress */
  +     zstd->dstream = ZSTD_createDStream();
  +     if (zstd->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.
  +      */
  +     zstd->nb = ZSTD_initDStream(zstd->dstream);
  +     if (ZSTD_isError(zstd->nb)) {
  +         fprintf(stderr, "ZSTD_initDStream() error : %s \n",
  +             ZSTD_getErrorName(zstd->nb));
  +         exit(11);   /* XXX */
  +     }
  +     zstd->nib = ZSTD_CStreamInSize();
  +     zstd->ib = xmalloc(zstd->nib);
  +#ifdef       NOTYET
  +     zstd->nob = BUFSIZ;
  +     zstd->ob = xmalloc(zstd->nob);
  +#else
  +     zstd->nob = ZSTD_CStreamOutSize();
  +     zstd->ob = xmalloc(zstd->nob);
  +#endif
  +    } else {                         /* compress */
  +     zstd->cstream = ZSTD_createCStream();
  +     if (zstd->cstream == NULL) {
  +         fprintf(stderr, "ZSTD_createCStream() error \n");
  +         exit(10);
  +     }
  +     zstd->nb = ZSTD_initCStream(zstd->cstream, level);
  +     if (ZSTD_isError(zstd->nb)) {
  +         fprintf(stderr, "ZSTD_initCStream() error : %s \n",
  +             ZSTD_getErrorName(zstd->nb));
  +         exit(11);   /* XXX */
  +     }
  +#ifdef       NOTYET
  +     zstd->nib = BUFSIZ;
  +     zstd->ib = xmalloc(zstd->nib);
  +#else
  +     zstd->nib = ZSTD_CStreamInSize();
  +     zstd->ib = xmalloc(zstd->nib);
  +#endif
  +     zstd->nob = ZSTD_CStreamOutSize();
  +     zstd->ob = xmalloc(zstd->nob);
  +    }
  +
  +    return rpmzstdLink(zstd);
  +}
  +
  +static
  +const char * rpmzstdError(rpmzstd zstd, int *errnum)
  +{
  +    return "";       /* XXX FIXME */
  +}
  +
  +int rpmzstdFlush(void * _zstd)
  +{
  +    rpmzstd zstd = (rpmzstd) _zstd;
  +    int rc = -2;
  +
  +    if (ZSTDF_ISSET(DECOMPRESS)) {   /* decompress */
  +assert(zstd->dstream);
  +    } else {                         /* compress */
  +assert(zstd->cstream);
  +     /* close frame */
  +     zstd->zob.dst  = zstd->ob;
  +     zstd->zob.size = zstd->nob;
  +     zstd->zob.pos  = 0;
  +     /* XXX nremain != 0 on small output buffers. Loop. */
  +     size_t nremain = ZSTD_flushStream(zstd->cstream, &zstd->zob);
  +     if (nremain) {
  +fprintf(stderr, "not fully flushed");
  +         rc = -1;
  +     } else {
  +         zstd->nw = fwrite(zstd->ob, 1, zstd->zob.pos, zstd->ofp);
  +assert(zstd->nw == zstd->zob.pos);
  +SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zstd->ob, zstd->zob.pos, 
zstd->ofp, zstd->nw);
  +         rc = 0;
  +     }
  +    }
  +
  +SPEW("<--\t%s(%p) rc %d\n", __FUNCTION__, zstd, rc);
  +    return rc;
  +}
  +
  +int rpmzstdClose(rpmzstd zstd)
  +{
  +    int rc = -2;
  +
  +SPEW("-->\t%s(%p)\n", __FUNCTION__, zstd);
  +    if (ZSTDF_ISSET(DECOMPRESS)) {   /* decompress */
  +assert(zstd->dstream);
  +    } else {                         /* compress */
  +assert(zstd->cstream);
  +     /* close frame */
  +     zstd->zob.dst  = zstd->ob;
  +     zstd->zob.size = zstd->nob;
  +     zstd->zob.pos  = 0;
  +     /* XXX nremain != 0 on small output buffers. Loop. */
  +     size_t nremain = ZSTD_endStream(zstd->cstream, &zstd->zob);
  +     if (nremain) {
  +fprintf(stderr, "not fully flushed");
  +         rc = -1;
  +     } else {
  +         zstd->nw = fwrite(zstd->ob, 1, zstd->zob.pos, zstd->ofp);
  +assert(zstd->nw == zstd->zob.pos);
  +SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zstd->ob, zstd->zob.pos, 
zstd->ofp, zstd->nw);
  +         rc = 0;
  +     }
  +     rpmzstdFini(zstd);      /* XXX rpmzstdFree? */
  +    }
  +
  +SPEW("<--\t%s(%p) rc %d\n", __FUNCTION__, zstd, rc);
  +    return rc;
  +}
  +
  +ssize_t rpmzstdRead(rpmzstd zstd, void *b, size_t nb)
  +{
  +    ssize_t rc = 0;
  +
  +SPEW("-->\t%s(%p,%p[%zd])\n", __FUNCTION__, zstd, b, nb);
  +
  +    zstd->zob.dst  = b;
  +    zstd->zob.size = nb;
  +    zstd->zob.pos  = 0;
  +    rc = 0;
  +    while (zstd->zob.pos < zstd->zob.size) {
  +     if (zstd->zib.pos >= zstd->zib.size) {
  +         zstd->nr = fread(zstd->ib, 1, zstd->nib, zstd->ifp);
  +         if (zstd->nr <= 0) {
  +             rc = zstd->nr;
  +             break;
  +         }
  +         zstd->zib.src  = zstd->ib;
  +         zstd->zib.size = zstd->nr;
  +         zstd->zib.pos  = 0;
  +     }
  +     while (zstd->zib.pos < zstd->zib.size) {
  +         zstd->nb = ZSTD_decompressStream(zstd->dstream, &zstd->zob, 
&zstd->zib);
  +SPEW("\t%s: nb %8zd\tzob %zu:%zu\tzib %zu:%zu\n", __FUNCTION__, zstd->nb, 
zstd->zob.pos, zstd->zob.size, zstd->zib.pos, zstd->zib.size);
  +         /* zstd->nb : size of next compressed block */
  +         if (ZSTD_isError(zstd->nb)) {
  +             fprintf(stderr, "ZSTD_decompressStream() error : %s \n",
  +                             ZSTD_getErrorName(zstd->nb));
  +             rc = -1;
  +             break;
  +         }
  +         if (zstd->zob.pos >= zstd->zob.size)
  +             break;
  +     }
  +    }
  +     rc = (rc >= 0 ? (ssize_t)zstd->zob.pos : rc);
  + 
  +SPEW("<--\t%s(%p,%p[%zd]) rc %ld\n", __FUNCTION__, zstd, b, nb, rc);
  +    return rc;
  +}
  +
  +ssize_t rpmzstdWrite(rpmzstd zstd, const void *b, size_t nb)
  +{
  +    ssize_t rc = -2;
  +
  +SPEW("-->\t%s(%p,%p[%zd])\n", __FUNCTION__, zstd, b, nb);
  +     zstd->zib.src  = b;
  +     zstd->zib.size = nb;
  +     zstd->zib.pos  = 0;
  +     rc = 0;
  +     while (zstd->zib.pos < zstd->zib.size) {
  +
  +         zstd->zob.dst  = zstd->ob;
  +         zstd->zob.size = zstd->nob;
  +         zstd->zob.pos  = 0;
  +
  +         zstd->nb = ZSTD_compressStream(zstd->cstream, &zstd->zob, 
&zstd->zib);
  +SPEW("\t%s: nb %8zd\tzob %zu:%zu\tzib %zu:%zu\n", "compress", zstd->nb, 
zstd->zob.pos, zstd->zob.size, zstd->zib.pos, zstd->zib.size);
  +         /* zstd->nb is guaranteed to be <= ZSTD_CStreamInSize() */
  +         if (ZSTD_isError(zstd->nb)) {
  +             fprintf(stderr, "ZSTD_compressStream() error : %s \n",
  +                             ZSTD_getErrorName(zstd->nb));
  +             rc = -1;
  +             break;
  +         }
  +
  +         if (zstd->zob.pos > 0) {
  +             zstd->nw = fwrite(zstd->ob, 1, zstd->zob.pos, zstd->ofp);
  +assert(zstd->nw == zstd->zob.pos);
  +SPEW("<--\tfwrite(%p, 1, %zu, %p) nw %zd\n", zstd->ob, zstd->zob.pos, 
zstd->ofp, zstd->nw);
  +         }
  +
  +     }
  +
  +     rc = (zstd->zib.pos == zstd->zib.size ? (ssize_t) zstd->zib.pos : -1);
  +
  +SPEW("<--\t%s(%p,%p[%zd]) rc %ld\n", __FUNCTION__, zstd, b, nb, rc);
  +    return rc;
  +}
  +
  +RPM_GNUC_CONST
  +int rpmzstdSeek(void * _zstd, _libio_pos_t pos, int whence)
  +{
  +    int rc = -2;
  +#ifdef USE_COOKIE_SEEK_POINTER
  +    _IO_off64_t p = *pos;
  +#else
  +    off_t p = pos;
  +#endif
  +    (void)p;
  +    return rc;
  +}
  +
  +rpmzstd rpmzstdOpen(const char * path, const char * fmode, int fdno, 
unsigned flags)
  +{
  +    return  rpmzstdNew(path, fmode, fdno, flags);
  +}
  +
  +RPM_GNUC_CONST
  +rpmzstd rpmzstdFdopen(void * _fdno, const char * fmode)
  +{
  +#ifdef       NOTYET
  +    int fdno = (int)((long)_fdno);   /* XXX hack */
  +    return  rpmzstdNew(NULL, fmode, fdno, 0);
  +#else
  +    return NULL;
  +#endif
  +}
  +
  +/* =============================================================== */
   static
   const char * rpmzsfError(gzFile gz, int *errnum)
   {
  @@ -258,20 +742,20 @@
        if (!sync_hint(zsf, buf[i]))
            continue;
        n = i + 1 - (begin - buf);
  -     rc = rpmzsfWrite(zsf->gz, (void *)begin, (unsigned)n);
  +     rc = rpmzstdWrite(zsf->zstd, (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 = rpmzsfFlush(zsf->gz);
  +     rc = rpmzstdFlush(zsf->zstd);
        if (rc < 0)
            return (n_written ? n_written : rc);
       }
       if (begin < buf + len) {
        n = len - (begin - buf);
  -     rc = rpmzsfWrite(zsf->gz, (void *)begin, (unsigned)n);
  +     rc = rpmzstdWrite(zsf->zstd, (void *)begin, (unsigned)n);
        if (rc < 0)
            return (n_written ? n_written : rc);
        n_written += rc;
  @@ -308,8 +792,8 @@
       mode_t mode = (fmode && fmode[0] == 'w' ? O_WRONLY : O_RDONLY);
   
       zsf = (zstdFILE) xcalloc(1, sizeof(*zsf));
  -    zsf->gz = rpmzsfOpen(path, fmode, -1);
  -    if (zsf->gz == NULL) {
  +    zsf->zstd = rpmzstdOpen(path, fmode, -1, RPMZSTD_FLAGS_NONE);
  +    if (zsf->zstd == NULL) {
        zsf = _free(zsf);
        return NULL;
       }
  @@ -331,8 +815,8 @@
       fdno = fdSetFdno(fd, -1);                /* XXX skip the fdio close */
       if (fdno < 0) return NULL;
       zsf = (zstdFILE) xcalloc(1, sizeof(*zsf));
  -    zsf->gz = rpmzsfOpen(NULL, fmode, fdno);
  -    if (zsf->gz == NULL) {
  +    zsf->zstd = rpmzstdOpen(NULL, fmode, fdno, RPMZSTD_FLAGS_NONE);
  +    if (zsf->zstd == NULL) {
        zsf = _free(zsf);
        return NULL;
       }
  @@ -348,7 +832,7 @@
       zstdFILE zsf;
       zsf = (zstdFILE) zstdFileno(fd);
       if (zsf == NULL) return -2;
  -    return rpmzsfFlush(zsf->gz);
  +    return rpmzstdFlush(zsf->zstd);
   }
   
   /* =============================================================== */
  @@ -364,11 +848,11 @@
       if (zsf == NULL) return -2;      /* XXX can't happen */
   
       fdstat_enter(fd, FDSTAT_READ);
  -    rc = rpmzsfRead(zsf->gz, buf, (unsigned)count);
  +    rc = rpmzstdRead(zsf->zstd, buf, (unsigned)count);
   DBGIO(fd, (stderr, "==>\tzstdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, 
(unsigned)count, (unsigned long)rc, fdbg(fd)));
       if (rc < 0) {
        int zerror = 0;
  -     fd->errcookie = rpmzsfError(zsf->gz, &zerror);
  +     fd->errcookie = rpmzstdError(zsf->zstd, &zerror);
   #ifdef       DYING
        if (zerror == Z_ERRNO) {
            fd->syserrno = errno;
  @@ -399,11 +883,11 @@
       if (enable_rsync)
        rc = rsyncable_write(zsf, (const unsigned char *)buf, (unsigned)count);
       else
  -     rc = rpmzsfWrite(zsf->gz, (void *)buf, (unsigned)count);
  +     rc = rpmzstdWrite(zsf->zstd, (void *)buf, (unsigned)count);
   DBGIO(fd, (stderr, "==>\tzstdWrite(%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 = rpmzsfError(zsf->gz, &zerror);
  +     fd->errcookie = rpmzstdError(zsf->zstd, &zerror);
   #ifdef       DYING
        if (zerror == Z_ERRNO) {
            fd->syserrno = errno;
  @@ -419,11 +903,6 @@
   static int zstdSeek(void * cookie, _libio_pos_t pos, int whence)
   {
       int rc;
  -#ifdef USE_COOKIE_SEEK_POINTER
  -    _IO_off64_t p = *pos;
  -#else
  -    off_t p = pos;
  -#endif
       FD_t fd = c2f(cookie);
       zstdFILE zsf;
   
  @@ -434,11 +913,11 @@
       if (zsf == NULL) return -2;      /* XXX can't happen */
   
       fdstat_enter(fd, FDSTAT_SEEK);
  -    rc = rpmzsfSeek(zsf->gz, (long)p, whence);
  -DBGIO(fd, (stderr, "==>\tzstdSeek(%p,%ld,%d) rc %lx %s\n", cookie, (long)p, 
whence, (unsigned long)rc, fdbg(fd)));
  +    rc = rpmzstdSeek(zsf->zstd, pos, whence);
  +DBGIO(fd, (stderr, "==>\tzstdSeek(%p,%p,%d) rc %lx %s\n", cookie, pos, 
whence, (unsigned long)rc, fdbg(fd)));
       if (rc < 0) {
        int zerror = 0;
  -     fd->errcookie = rpmzsfError(zsf->gz, &zerror);
  +     fd->errcookie = rpmzstdError(zsf->zstd, &zerror);
   #ifdef       DYING
        if (zerror == Z_ERRNO) {
            fd->syserrno = errno;
  @@ -461,8 +940,8 @@
       if (zsf == NULL) return -2;      /* XXX can't happen */
   
       fdstat_enter(fd, FDSTAT_CLOSE);
  -    rc = rpmzsfClose(zsf->gz);
  -    zsf->gz = NULL;
  +    rc = rpmzstdClose(zsf->zstd);
  +    zsf->zstd = rpmzstdFree(zsf->zstd);
       zsf = _free(zsf);
   
       /* XXX TODO: preserve fd if errors */
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                [email protected]

Reply via email to