void XzCompress::Decode(void) { // get buffer char chunk[1024]; char *zbuf = (char *)calloc(1, 1024); char *chunkbuf = zbuf; int chunklen; unsigned long zlen = 0; while((chunklen = GetChars(chunk, 1023))) { memcpy(chunkbuf, chunk, chunklen); zlen += chunklen; if (chunklen < 1023) break; else zbuf = (char *)realloc(zbuf, zlen + 1024); chunkbuf = zbuf + zlen; } //printf("Decoding complength{%ld} uncomp{%ld}\n", zlen, blen); if (zlen) { unsigned long blen = zlen*20; // trust compression is less than 1000% char *buf = new char[blen]; //printf("Doing decompress {%s}\n", zbuf); slen = 0; size_t zpos = 0; size_t bpos = 0; switch (lzma_block_buffer_decode(&block, NULL, (const uint8_t*)zbuf, &zpos, (size_t)zlen, (uint8_t*)buf, &bpos, (size_t)&blen)){ case LZMA_OK: SendChars(buf, blen); slen = blen; break; case LZMA_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during decompression.\n"); break; case LZMA_BUF_ERROR: fprintf(stderr, "ERROR: not enough room in the out buffer during decompression.\n"); break; case LZMA_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data during decompression.\n"); break; default: fprintf(stderr, "ERROR: an unknown error occured during decompression.\n"); break; } delete [] buf; } else { fprintf(stderr, "ERROR: no buffer to decompress!\n"); } //printf("Finished decoding\n"); free (zbuf); }
static file_ptr lzma_pread (struct bfd *nbfd, void *stream, void *buf, file_ptr nbytes, file_ptr offset) { struct lzma_stream *lstream = stream; bfd_size_type chunk_size; lzma_index_iter iter; gdb_byte *compressed, *uncompressed; file_ptr block_offset; lzma_filter filters[LZMA_FILTERS_MAX + 1]; lzma_block block; size_t compressed_pos, uncompressed_pos; file_ptr res; res = 0; while (nbytes > 0) { if (lstream->data == NULL || lstream->data_start > offset || offset >= lstream->data_end) { asection *section = lstream->section; lzma_index_iter_init (&iter, lstream->index); if (lzma_index_iter_locate (&iter, offset)) break; compressed = xmalloc (iter.block.total_size); block_offset = section->filepos + iter.block.compressed_file_offset; if (bfd_seek (section->owner, block_offset, SEEK_SET) != 0 || bfd_bread (compressed, iter.block.total_size, section->owner) != iter.block.total_size) { xfree (compressed); break; } uncompressed = xmalloc (iter.block.uncompressed_size); memset (&block, 0, sizeof (block)); block.filters = filters; block.header_size = lzma_block_header_size_decode (compressed[0]); if (lzma_block_header_decode (&block, &gdb_lzma_allocator, compressed) != LZMA_OK) { xfree (compressed); xfree (uncompressed); break; } compressed_pos = block.header_size; uncompressed_pos = 0; if (lzma_block_buffer_decode (&block, &gdb_lzma_allocator, compressed, &compressed_pos, iter.block.total_size, uncompressed, &uncompressed_pos, iter.block.uncompressed_size) != LZMA_OK) { xfree (compressed); xfree (uncompressed); break; } xfree (compressed); xfree (lstream->data); lstream->data = uncompressed; lstream->data_start = iter.block.uncompressed_file_offset; lstream->data_end = (iter.block.uncompressed_file_offset + iter.block.uncompressed_size); } chunk_size = min (nbytes, lstream->data_end - offset); memcpy (buf, lstream->data + offset - lstream->data_start, chunk_size); buf = (gdb_byte *) buf + chunk_size; offset += chunk_size; nbytes -= chunk_size; res += chunk_size; } return res; }