Skip to content

Commit ac7ba7c

Browse files
committed
zchunk: support extracting of streams other than "1"
1 parent a88c9f1 commit ac7ba7c

3 files changed

Lines changed: 27 additions & 16 deletions

File tree

ext/solv_xfopen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ static void *zchunkopen(const char *path, const char *mode, int fd)
520520
fp = fopen(path, mode);
521521
if (!fp)
522522
return 0;
523-
f = solv_zchunk_open(fp);
523+
f = solv_zchunk_open(fp, 1);
524524
if (!f)
525525
fclose(fp);
526526
return cookieopen(f, mode, (ssize_t (*)(void *, char *, size_t))solv_zchunk_read, 0, (int (*)(void *))solv_zchunk_close);

ext/solv_zchunk.c

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,12 @@ struct solv_zchunk {
3232
int data_chk_len;
3333
Chksum *data_chk; /* for data checksum verification */
3434

35-
unsigned int chunk_chk_type;
35+
unsigned int chunk_chk_type; /* chunk checksum */
3636
int chunk_chk_len;
3737
Id chunk_chk_id;
3838

39-
unsigned int nchunks; /* chunks left */
39+
unsigned int streamid; /* stream we are reading */
40+
unsigned int nchunks; /* chunks left */
4041
unsigned char *chunks;
4142

4243
ZSTD_DCtx *dctx;
@@ -141,9 +142,14 @@ nextchunk(struct solv_zchunk *zck, unsigned int streamid)
141142

142143
for (;;)
143144
{
144-
if (zck->nchunks == 0 || p >= zck->hdr_end)
145+
if (zck->nchunks == 0)
146+
{
147+
zck->chunks = p;
148+
return 1; /* EOF reached */
149+
}
150+
if (p >= zck->hdr_end)
145151
return 0;
146-
sid = streamid;
152+
sid = streamid ? 1 : 0;
147153
/* check if this is the correct stream */
148154
if ((zck->flags & 1) != 0 && (p = getuint(p, zck->hdr_end, &sid)) == 0)
149155
return 0;
@@ -235,7 +241,7 @@ open_error(struct solv_zchunk *zck)
235241
}
236242

237243
struct solv_zchunk *
238-
solv_zchunk_open(FILE *fp)
244+
solv_zchunk_open(FILE *fp, unsigned int streamid)
239245
{
240246
struct solv_zchunk *zck;
241247
unsigned char *p;
@@ -246,6 +252,7 @@ solv_zchunk_open(FILE *fp)
246252
unsigned int lead_size;
247253
unsigned int preface_size;
248254
unsigned int index_size;
255+
unsigned int nchunks;
249256

250257
zck = solv_calloc(1, sizeof(*zck));
251258

@@ -314,19 +321,22 @@ solv_zchunk_open(FILE *fp)
314321
if (zck->chunk_chk_len < 0)
315322
return open_error(zck);
316323

317-
if ((p = getuint(p, zck->hdr_end, &zck->nchunks)) == 0 || zck->nchunks > MAX_CHUNK_CNT)
324+
if ((p = getuint(p, zck->hdr_end, &nchunks)) == 0 || nchunks > MAX_CHUNK_CNT)
318325
return open_error(zck);
319-
zck->nchunks += 1; /* add 1 for the dict chunk */
320-
zck->chunks = p;
321326

322-
/* setup decompression context */
327+
/* setup decompressor */
323328
if (zck->comp == 2)
324329
{
325-
zck->dctx = ZSTD_createDCtx();
326-
if (!zck->dctx)
330+
if ((zck->dctx = ZSTD_createDCtx()) == 0)
327331
return open_error(zck);
328332
}
333+
329334
zck->fp = fp;
335+
zck->chunks = p;
336+
zck->nchunks = 1; /* the dict stream */
337+
zck->streamid = streamid;
338+
if (streamid == 0)
339+
return zck;
330340

331341
/* setup dictionary */
332342
if (!nextchunk(zck, 0))
@@ -347,7 +357,8 @@ solv_zchunk_open(FILE *fp)
347357
zck->buf_used = 0;
348358
zck->buf_avail = 0;
349359

350-
/* ready to go */
360+
/* ready to read the rest of the chunks */
361+
zck->nchunks = nchunks;
351362
return zck;
352363
}
353364

@@ -367,14 +378,14 @@ solv_zchunk_read(struct solv_zchunk *zck, char *buf, size_t len)
367378
if (!zck->nchunks)
368379
{
369380
/* verify data checksum if requested */
370-
if (zck->data_chk && memcmp(solv_chksum_get(zck->data_chk, 0), zck->data_chk_ptr, zck->data_chk_len) != 0) {
381+
if (zck->streamid != 0 && zck->data_chk && memcmp(solv_chksum_get(zck->data_chk, 0), zck->data_chk_ptr, zck->data_chk_len) != 0) {
371382
zck->eof = 2;
372383
return -1;
373384
}
374385
zck->eof = 1;
375386
return n;
376387
}
377-
if (!nextchunk(zck, 1))
388+
if (!nextchunk(zck, zck->streamid))
378389
{
379390
zck->eof = 2;
380391
return -1;

ext/solv_zchunk.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
struct solv_zchunk;
99

10-
extern struct solv_zchunk *solv_zchunk_open(FILE *fp);
10+
extern struct solv_zchunk *solv_zchunk_open(FILE *fp, unsigned int streamid);
1111
extern ssize_t solv_zchunk_read(struct solv_zchunk *zck, char *buf, size_t len);
1212
extern int solv_zchunk_close(struct solv_zchunk *zck);
1313

0 commit comments

Comments
 (0)