Example #1
0
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);
}
Example #2
0
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;
}