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; }
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; }
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; }
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; }