Ejemplo n.º 1
0
/**
 * gsf_vba_inflate:
 * @input: stream to read from
 * @offset: offset into it for start byte of compressed stream
 * @size: size of the returned array
 * @add_null_terminator: whenever add or not null at the end of array
 * 
 * Decompresses VBA stream.
 * 
 * Return value: A pointer to guint8 array
 **/
guint8 *
gsf_vba_inflate (GsfInput *input, gsf_off_t offset, int *size, gboolean add_null_terminator)
{
	guint8 sig;
	GByteArray *res;
	gsf_off_t length;

	res = g_byte_array_new();

	gsf_input_read (input, 1, &sig);
	if (1 != sig) /* should start with 0x01 */
		return NULL;
	offset++;

	length = gsf_input_size (input);
	while (offset < length) {
		GsfInput *chunk;
		guint16 chunk_hdr;
		guint8 const *tmp;

		tmp = gsf_input_read (input, 2, NULL);
		if (!tmp)
			break;

		chunk_hdr = GSF_LE_GET_GUINT16 (tmp);
		offset += 2;

		if (0xB000 == (chunk_hdr&0xF000) && (chunk_hdr&0xFFF) > 0 && (length - offset < 4094)){
			if (length < offset + (chunk_hdr&0xFFF))
				break;
			chunk = gsf_input_proxy_new_section (input, offset, (gsf_off_t) (chunk_hdr&0xFFF) + 1);
			offset += (chunk_hdr&0xFFF) + 1;
		} else {
			if (length < offset + 4094){
				chunk = gsf_input_proxy_new_section (input, offset, length-offset);
				offset = length;
			} else {
				chunk = gsf_input_proxy_new_section (input, offset, 4094);
				offset += 4094;
			}
		}
		if (chunk) {
			GByteArray *tmpres = gsf_msole_inflate (chunk, 0);
			gsf_input_seek (input, offset, G_SEEK_CUR);
			g_byte_array_append (res, tmpres->data, tmpres->len);
			g_byte_array_free (tmpres, TRUE);
			g_object_unref (chunk);
		}
	}
	
	if (res == NULL)
		return NULL;
	if (add_null_terminator)
		g_byte_array_append (res, "", 1);
	*size = res->len;

	return g_byte_array_free (res, FALSE);
}
Ejemplo n.º 2
0
static GsfInput *
gsf_infile_tar_child_by_index (GsfInfile *infile, int target, GError **err)
{
	GsfInfileTar *tar = GSF_INFILE_TAR (infile);
	const TarChild *c;

	if (err)
		*err = NULL;

	if (target < 0 || (unsigned)target >= tar->children->len)
		return NULL;

	c = &g_array_index (tar->children, TarChild, target);
	if (c->dir)
		return g_object_ref (c->dir);
	else {
		GsfInput *input = gsf_input_proxy_new_section (tar->source,
							       c->offset,
							       c->length);
		gsf_input_set_name (input, c->name);
		return input;
	}
}