static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) { FILE *fp; char buf[BLOCKSIZE]; int fd, len, offset = 0; if (mar_ensure_parent_dir(item->name)) return -1; #ifdef XP_WIN fd = _open(item->name, _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY, item->flags); #else fd = creat(item->name, item->flags); #endif if (fd == -1) return -1; fp = fdopen(fd, "wb"); if (!fp) return -1; while ((len = mar_read(mar, item, offset, buf, sizeof(buf))) > 0) { if (fwrite(buf, len, 1, fp) != 1) break; offset += len; } fclose(fp); return len == 0 ? 0 : -1; }
int ArchiveReader::ExtractItemToStream(const MarItem *item, FILE *fp) { /* decompress the data chunk by chunk */ bz_stream strm; int offset, inlen, outlen, ret = OK; memset(&strm, 0, sizeof(strm)); if (BZ2_bzDecompressInit(&strm, 0, 0) != BZ_OK) return UNEXPECTED_BZIP_ERROR; offset = 0; for (;;) { if (!item->length) { ret = UNEXPECTED_MAR_ERROR; break; } if (offset < (int) item->length && strm.avail_in == 0) { inlen = mar_read(mArchive, item, offset, inbuf, inbuf_size); if (inlen <= 0) return READ_ERROR; offset += inlen; strm.next_in = inbuf; strm.avail_in = inlen; } strm.next_out = outbuf; strm.avail_out = outbuf_size; ret = BZ2_bzDecompress(&strm); if (ret != BZ_OK && ret != BZ_STREAM_END) { ret = UNEXPECTED_BZIP_ERROR; break; } outlen = outbuf_size - strm.avail_out; if (outlen) { if (fwrite(outbuf, outlen, 1, fp) != 1) { ret = WRITE_ERROR_EXTRACT; break; } } if (ret == BZ_STREAM_END) { ret = OK; break; } } BZ2_bzDecompressEnd(&strm); return ret; }