コード例 #1
0
ファイル: dmg.c プロジェクト: Blopeur/qemu-heca
static inline int dmg_read_chunk(BlockDriverState *bs, int sector_num)
{
    BDRVDMGState *s = bs->opaque;

    if(!is_sector_in_chunk(s,s->current_chunk,sector_num)) {
	int ret;
	uint32_t chunk = search_chunk(s,sector_num);

	if(chunk>=s->n_chunks)
	    return -1;

	s->current_chunk = s->n_chunks;
	switch(s->types[chunk]) {
	case 0x80000005: { /* zlib compressed */
	    int i;

	    /* we need to buffer, because only the chunk as whole can be
	     * inflated. */
	    i=0;
	    do {
                ret = bdrv_pread(bs->file, s->offsets[chunk] + i,
                                 s->compressed_chunk+i, s->lengths[chunk]-i);
		if(ret<0 && errno==EINTR)
		    ret=0;
		i+=ret;
	    } while(ret>=0 && ret+i<s->lengths[chunk]);

	    if (ret != s->lengths[chunk])
		return -1;

	    s->zstream.next_in = s->compressed_chunk;
	    s->zstream.avail_in = s->lengths[chunk];
	    s->zstream.next_out = s->uncompressed_chunk;
	    s->zstream.avail_out = 512*s->sectorcounts[chunk];
	    ret = inflateReset(&s->zstream);
	    if(ret != Z_OK)
		return -1;
	    ret = inflate(&s->zstream, Z_FINISH);
	    if(ret != Z_STREAM_END || s->zstream.total_out != 512*s->sectorcounts[chunk])
		return -1;
	    break; }
	case 1: /* copy */
	    ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->uncompressed_chunk, s->lengths[chunk]);
	    if (ret != s->lengths[chunk])
		return -1;
	    break;
	case 2: /* zero */
	    memset(s->uncompressed_chunk, 0, 512*s->sectorcounts[chunk]);
	    break;
	}
	s->current_chunk = chunk;
    }
    return 0;
}
コード例 #2
0
ファイル: block-dmg.c プロジェクト: CPFL/gxen
static inline int dmg_read_chunk(BDRVDMGState *s,int sector_num)
{
    if(!is_sector_in_chunk(s,s->current_chunk,sector_num)) {
	int ret;
	uint32_t chunk = search_chunk(s,sector_num);

	if(chunk>=s->n_chunks)
	    return -1;

	s->current_chunk = s->n_chunks;
	switch(s->types[chunk]) {
	case 0x80000005: { /* zlib compressed */
	    ret = lseek(s->fd, s->offsets[chunk], SEEK_SET);
	    if(ret<0)
		return -1;

	    /* we need to buffer, because only the chunk as whole can be
	     * inflated. */
	    ret = qemu_read_ok(s->fd, s->compressed_chunk, s->lengths[chunk]);
	    if (ret < 0)
	        return -1;

	    s->zstream.next_in = s->compressed_chunk;
	    s->zstream.avail_in = s->lengths[chunk];
	    s->zstream.next_out = s->uncompressed_chunk;
	    s->zstream.avail_out = 512*s->sectorcounts[chunk];
	    ret = inflateReset(&s->zstream);
	    if(ret != Z_OK)
		return -1;
	    ret = inflate(&s->zstream, Z_FINISH);
	    if(ret != Z_STREAM_END || s->zstream.total_out != 512*s->sectorcounts[chunk])
		return -1;
	    break; }
	case 1: /* copy */
	    ret = qemu_read_ok(s->fd, s->uncompressed_chunk, s->lengths[chunk]);
	    if (ret < 0)
		return -1;
	    break;
	case 2: /* zero */
	    memset(s->uncompressed_chunk, 0, 512*s->sectorcounts[chunk]);
	    break;
	}
	s->current_chunk = chunk;
    }
    return 0;
}
コード例 #3
0
ファイル: dmg.c プロジェクト: heiher/qemu
static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
{
    BDRVDMGState *s = bs->opaque;

    if (!is_sector_in_chunk(s, s->current_chunk, sector_num)) {
        int ret;
        uint32_t chunk = search_chunk(s, sector_num);

        if (chunk >= s->n_chunks) {
            return -1;
        }

        s->current_chunk = s->n_chunks;
        switch (s->types[chunk]) { /* block entry type */
        case 0x80000005: { /* zlib compressed */
            /* we need to buffer, because only the chunk as whole can be
             * inflated. */
            ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->compressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }

            s->zstream.next_in = s->compressed_chunk;
            s->zstream.avail_in = s->lengths[chunk];
            s->zstream.next_out = s->uncompressed_chunk;
            s->zstream.avail_out = 512 * s->sectorcounts[chunk];
            ret = inflateReset(&s->zstream);
            if (ret != Z_OK) {
                return -1;
            }
            ret = inflate(&s->zstream, Z_FINISH);
            if (ret != Z_STREAM_END ||
                    s->zstream.total_out != 512 * s->sectorcounts[chunk]) {
                return -1;
            }
            break;
        }
        case 0x80000006: /* bzip2 compressed */
            if (!dmg_uncompress_bz2) {
                break;
            }
            /* we need to buffer, because only the chunk as whole can be
             * inflated. */
            ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->compressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }

            ret = dmg_uncompress_bz2((char *)s->compressed_chunk,
                                     (unsigned int) s->lengths[chunk],
                                     (char *)s->uncompressed_chunk,
                                     (unsigned int)
                                     (512 * s->sectorcounts[chunk]));
            if (ret < 0) {
                return ret;
            }
            break;
        case 1: /* copy */
            ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->uncompressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }
            break;
        case 2: /* zero */
            /* see dmg_read, it is treated specially. No buffer needs to be
             * pre-filled, the zeroes can be set directly. */
            break;
        }
        s->current_chunk = chunk;
    }
    return 0;
}
コード例 #4
0
ファイル: dmg.c プロジェクト: Jameshzc/qemu
static inline int dmg_read_chunk(BlockDriverState *bs, uint64_t sector_num)
{
    BDRVDMGState *s = bs->opaque;

    if (!is_sector_in_chunk(s, s->current_chunk, sector_num)) {
        int ret;
        uint32_t chunk = search_chunk(s, sector_num);
#ifdef CONFIG_BZIP2
        uint64_t total_out;
#endif

        if (chunk >= s->n_chunks) {
            return -1;
        }

        s->current_chunk = s->n_chunks;
        switch (s->types[chunk]) { /* block entry type */
        case 0x80000005: { /* zlib compressed */
            /* we need to buffer, because only the chunk as whole can be
             * inflated. */
            ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
                             s->compressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }

            s->zstream.next_in = s->compressed_chunk;
            s->zstream.avail_in = s->lengths[chunk];
            s->zstream.next_out = s->uncompressed_chunk;
            s->zstream.avail_out = 512 * s->sectorcounts[chunk];
            ret = inflateReset(&s->zstream);
            if (ret != Z_OK) {
                return -1;
            }
            ret = inflate(&s->zstream, Z_FINISH);
            if (ret != Z_STREAM_END ||
                s->zstream.total_out != 512 * s->sectorcounts[chunk]) {
                return -1;
            }
            break; }
#ifdef CONFIG_BZIP2
        case 0x80000006: /* bzip2 compressed */
            /* we need to buffer, because only the chunk as whole can be
             * inflated. */
            ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
                             s->compressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }

            ret = BZ2_bzDecompressInit(&s->bzstream, 0, 0);
            if (ret != BZ_OK) {
                return -1;
            }
            s->bzstream.next_in = (char *)s->compressed_chunk;
            s->bzstream.avail_in = (unsigned int) s->lengths[chunk];
            s->bzstream.next_out = (char *)s->uncompressed_chunk;
            s->bzstream.avail_out = (unsigned int) 512 * s->sectorcounts[chunk];
            ret = BZ2_bzDecompress(&s->bzstream);
            total_out = ((uint64_t)s->bzstream.total_out_hi32 << 32) +
                        s->bzstream.total_out_lo32;
            BZ2_bzDecompressEnd(&s->bzstream);
            if (ret != BZ_STREAM_END ||
                total_out != 512 * s->sectorcounts[chunk]) {
                return -1;
            }
            break;
#endif /* CONFIG_BZIP2 */
        case 1: /* copy */
            ret = bdrv_pread(bs->file->bs, s->offsets[chunk],
                             s->uncompressed_chunk, s->lengths[chunk]);
            if (ret != s->lengths[chunk]) {
                return -1;
            }
            break;
        case 2: /* zero */
            /* see dmg_read, it is treated specially. No buffer needs to be
             * pre-filled, the zeroes can be set directly. */
            break;
        }
        s->current_chunk = chunk;
    }
    return 0;
}