]> git.ipfire.org Git - thirdparty/libsolv.git/commitdiff
zchunk: support extracting of streams other than "1"
authorMichael Schroeder <mls@suse.de>
Wed, 18 Jul 2018 11:36:11 +0000 (13:36 +0200)
committerMichael Schroeder <mls@suse.de>
Wed, 18 Jul 2018 11:36:11 +0000 (13:36 +0200)
ext/solv_xfopen.c
ext/solv_zchunk.c
ext/solv_zchunk.h

index c9623f1f80ff4860c12d28cfed2c2896e866f683..a74762f262ca6e5ef68262e4f715b1e9703156f6 100644 (file)
@@ -520,7 +520,7 @@ static void *zchunkopen(const char *path, const char *mode, int fd)
     fp = fopen(path, mode);
   if (!fp)
     return 0;
-  f = solv_zchunk_open(fp);
+  f = solv_zchunk_open(fp, 1);
   if (!f)
     fclose(fp);
   return cookieopen(f, mode, (ssize_t (*)(void *, char *, size_t))solv_zchunk_read, 0, (int (*)(void *))solv_zchunk_close);
index 5138f973c8805717ecde4e863428a0b8ad5b3231..6df0caffafa6976434183e9ca7ae33fc91584605 100644 (file)
@@ -32,11 +32,12 @@ struct solv_zchunk {
   int data_chk_len;
   Chksum *data_chk;    /* for data checksum verification */
 
-  unsigned int chunk_chk_type;
+  unsigned int chunk_chk_type; /* chunk checksum */
   int chunk_chk_len;
   Id chunk_chk_id;
 
-  unsigned int nchunks;        /* chunks left */
+  unsigned int streamid;       /* stream we are reading */
+  unsigned int nchunks;                /* chunks left */
   unsigned char *chunks;
 
   ZSTD_DCtx *dctx;
@@ -141,9 +142,14 @@ nextchunk(struct solv_zchunk *zck, unsigned int streamid)
 
   for (;;)
     {
-      if (zck->nchunks == 0 || p >= zck->hdr_end)
+      if (zck->nchunks == 0)
+       {
+         zck->chunks = p;
+         return 1;             /* EOF reached */
+       }
+      if (p >= zck->hdr_end)
        return 0;
-      sid = streamid;
+      sid = streamid ? 1 : 0;
       /* check if this is the correct stream */
       if ((zck->flags & 1) != 0 && (p = getuint(p, zck->hdr_end, &sid)) == 0)
        return 0;
@@ -235,7 +241,7 @@ open_error(struct solv_zchunk *zck)
 }
 
 struct solv_zchunk *
-solv_zchunk_open(FILE *fp)
+solv_zchunk_open(FILE *fp, unsigned int streamid)
 {
   struct solv_zchunk *zck;
   unsigned char *p;
@@ -246,6 +252,7 @@ solv_zchunk_open(FILE *fp)
   unsigned int lead_size;
   unsigned int preface_size;
   unsigned int index_size;
+  unsigned int nchunks;
 
   zck = solv_calloc(1, sizeof(*zck));
 
@@ -314,19 +321,22 @@ solv_zchunk_open(FILE *fp)
   if (zck->chunk_chk_len < 0)
     return open_error(zck);
   
-  if ((p = getuint(p, zck->hdr_end, &zck->nchunks)) == 0 || zck->nchunks > MAX_CHUNK_CNT)
+  if ((p = getuint(p, zck->hdr_end, &nchunks)) == 0 || nchunks > MAX_CHUNK_CNT)
     return open_error(zck);
-  zck->nchunks += 1;   /* add 1 for the dict chunk */
-  zck->chunks = p;
 
-  /* setup decompression context */
+  /* setup decompressor */
   if (zck->comp == 2)
     {
-      zck->dctx = ZSTD_createDCtx();
-      if (!zck->dctx)
+      if ((zck->dctx = ZSTD_createDCtx()) == 0)
        return open_error(zck);
     }
+
   zck->fp = fp;
+  zck->chunks = p;
+  zck->nchunks = 1;                    /* the dict stream */
+  zck->streamid = streamid;
+  if (streamid == 0)
+    return zck;        
 
   /* setup dictionary */
   if (!nextchunk(zck, 0))
@@ -347,7 +357,8 @@ solv_zchunk_open(FILE *fp)
   zck->buf_used = 0;
   zck->buf_avail = 0;
 
-  /* ready to go */
+  /* ready to read the rest of the chunks */
+  zck->nchunks = nchunks;
   return zck;
 }
 
@@ -367,14 +378,14 @@ solv_zchunk_read(struct solv_zchunk *zck, char *buf, size_t len)
          if (!zck->nchunks)
            {
              /* verify data checksum if requested */
-             if (zck->data_chk && memcmp(solv_chksum_get(zck->data_chk, 0), zck->data_chk_ptr, zck->data_chk_len) != 0) {
+             if (zck->streamid != 0 && zck->data_chk && memcmp(solv_chksum_get(zck->data_chk, 0), zck->data_chk_ptr, zck->data_chk_len) != 0) {
                zck->eof = 2;
                return -1;
              }
              zck->eof = 1;
              return n;
            }
-         if (!nextchunk(zck, 1))
+         if (!nextchunk(zck, zck->streamid))
            {
              zck->eof = 2;
              return -1;
index 13a9b5d6b287c7d5c26d10be90214fe1f97b3501..9d7348663a613c923611c55b16cbd5d530bf97b6 100644 (file)
@@ -7,7 +7,7 @@
 
 struct solv_zchunk;
 
-extern struct solv_zchunk *solv_zchunk_open(FILE *fp);
+extern struct solv_zchunk *solv_zchunk_open(FILE *fp, unsigned int streamid);
 extern ssize_t solv_zchunk_read(struct solv_zchunk *zck, char *buf, size_t len);
 extern int solv_zchunk_close(struct solv_zchunk *zck);