int process_raw_chunk(void *buf, T_Emmc_Handle *p_handle, u32 blocks, u32 blk_sz, u32 *crc32) { u64 len = (u64)blocks * blk_sz; int ret; int chunk; while (len) { chunk = (len > COPY_BUF_SIZE) ? COPY_BUF_SIZE : len; ret = read_all(buf, g_buf_index, copybuf, chunk); if (ret != chunk) { printf("read returned an error copying a raw chunk: %d %d\n", ret, chunk); return -1; } *crc32 = sparse_crc32(*crc32, copybuf, chunk); ret = write_all(p_handle, copybuf, chunk); if (ret != chunk) { printf("write returned an error copying a raw chunk\n"); return -1; } len -= chunk; } return blocks; }
static int write_sparse_fill_chunk(struct output_file *out, unsigned int len, uint32_t fill_val) { chunk_header_t chunk_header; int rnd_up_len, zero_len, count; int ret; unsigned int i; /* Round up the fill length to a multiple of the block size */ rnd_up_len = ALIGN(len, out->block_size); /* Finally we can safely emit a chunk of data */ chunk_header.chunk_type = CHUNK_TYPE_FILL; chunk_header.reserved1 = 0; chunk_header.chunk_sz = rnd_up_len / out->block_size; chunk_header.total_sz = CHUNK_HEADER_LEN + sizeof(fill_val); ret = out->ops->write(out, &chunk_header, sizeof(chunk_header)); if (ret < 0) return -1; ret = out->ops->write(out, &fill_val, sizeof(fill_val)); if (ret < 0) return -1; if (out->use_crc) { count = out->block_size / sizeof(uint32_t); while (count--) out->crc32 = sparse_crc32(out->crc32, &fill_val, sizeof(uint32_t)); } out->cur_out_ptr += rnd_up_len; out->chunk_cnt++; return 0; }
int process_fill_chunk(void *buf, T_Emmc_Handle *p_handle, u32 blocks, u32 blk_sz, u32 *crc32) { u64 len = (u64)blocks * blk_sz; int ret; int chunk; u32 fill_val; u32 *fillbuf; unsigned int i; /* Fill copy_buf with the fill value */ ret = read_all(buf, g_buf_index, &fill_val, sizeof(fill_val)); fillbuf = (u32 *)copybuf; for (i = 0; i < (COPY_BUF_SIZE / sizeof(fill_val)); i++) { fillbuf[i] = fill_val; } while (len) { chunk = (len > COPY_BUF_SIZE) ? COPY_BUF_SIZE : len; *crc32 = sparse_crc32(*crc32, copybuf, chunk); ret = write_all(p_handle, copybuf, chunk); if (ret != chunk) { printf("write returned an error copying a raw chunk\n"); return -1; } len -= chunk; } return blocks; }
int process_skip_chunk(FILE *out, u32 blocks, u32 blk_sz, u32 *crc32) { /* len needs to be 64 bits, as the sparse file specifies the skip amount * as a 32 bit value of blocks. */ u64 len = (u64)blocks * blk_sz; u64 len_save; u32 skip_chunk; /* Fseek takes the offset as a long, which may be 32 bits on some systems. * So, lets do a sequence of fseeks() with SEEK_CUR to get the file pointer * where we want it. */ len_save = len; while (len) { skip_chunk = (len > 0x80000000) ? 0x80000000 : len; fseek(out, skip_chunk, SEEK_CUR); len -= skip_chunk; } /* And compute the CRC of the skipped region a chunk at a time */ len = len_save; while (len) { skip_chunk = (skip_chunk > blk_sz) ? blk_sz : skip_chunk; *crc32 = sparse_crc32(*crc32, zerobuf, skip_chunk); len -= skip_chunk; } return blocks; }
static int write_sparse_data_chunk(struct output_file *out, unsigned int len, void *data) { chunk_header_t chunk_header; int rnd_up_len, zero_len; int ret; /* Round up the data length to a multiple of the block size */ rnd_up_len = ALIGN(len, out->block_size); zero_len = rnd_up_len - len; /* Finally we can safely emit a chunk of data */ chunk_header.chunk_type = CHUNK_TYPE_RAW; chunk_header.reserved1 = 0; chunk_header.chunk_sz = rnd_up_len / out->block_size; chunk_header.total_sz = CHUNK_HEADER_LEN + rnd_up_len; ret = out->ops->write(out, &chunk_header, sizeof(chunk_header)); if (ret < 0) return -1; ret = out->ops->write(out, data, len); if (ret < 0) return -1; if (zero_len) { ret = out->ops->write(out, out->zero_buf, zero_len); if (ret < 0) return -1; } if (out->use_crc) { out->crc32 = sparse_crc32(out->crc32, data, len); if (zero_len) out->crc32 = sparse_crc32(out->crc32, out->zero_buf, zero_len); } out->cur_out_ptr += rnd_up_len; out->chunk_cnt++; return 0; }
int GetCrc32(uint32_t* crc32, int64_t len) override { int chunk; int ret; while (len) { chunk = std::min(len, COPY_BUF_SIZE); ret = read_all(fd, copybuf, chunk); if (ret < 0) { return ret; } *crc32 = sparse_crc32(*crc32, copybuf, chunk); len -= chunk; } return 0; }
static int process_skip_chunk(struct sparse_file *s, unsigned int chunk_size, int fd __unused, unsigned int blocks, unsigned int block __unused, uint32_t *crc32) { if (chunk_size != 0) { return -EINVAL; } if (crc32) { int64_t len = (int64_t)blocks * s->block_size; memset(copybuf, 0, COPY_BUF_SIZE); while (len) { int chunk = min(len, COPY_BUF_SIZE); *crc32 = sparse_crc32(*crc32, copybuf, chunk); len -= chunk; } } return 0; }
int process_raw_chunk(FILE *in, FILE *out, u32 blocks, u32 blk_sz, u32 *crc32) { u64 len = (u64)blocks * blk_sz; int chunk; while (len) { chunk = (len > COPY_BUF_SIZE) ? COPY_BUF_SIZE : len; if (fread(copybuf, chunk, 1, in) != 1) { fprintf(stderr, "fread returned an error copying a raw chunk\n"); exit(-1); } *crc32 = sparse_crc32(*crc32, copybuf, chunk); if (fwrite(copybuf, chunk, 1, out) != 1) { fprintf(stderr, "fwrite returned an error copying a raw chunk\n"); exit(-1); } len -= chunk; } return blocks; }
static int process_fill_chunk(struct sparse_file *s, unsigned int chunk_size, int fd, unsigned int blocks, unsigned int block, uint32_t *crc32) { int ret; int chunk; int64_t len = (int64_t)blocks * s->block_size; uint32_t fill_val; uint32_t *fillbuf; unsigned int i; if (chunk_size != sizeof(fill_val)) { return -EINVAL; } ret = read_all(fd, &fill_val, sizeof(fill_val)); if (ret < 0) { return ret; } ret = sparse_file_add_fill(s, fill_val, len, block); if (ret < 0) { return ret; } if (crc32) { /* Fill copy_buf with the fill value */ fillbuf = (uint32_t *)copybuf; for (i = 0; i < (COPY_BUF_SIZE / sizeof(fill_val)); i++) { fillbuf[i] = fill_val; } while (len) { chunk = min(len, COPY_BUF_SIZE); *crc32 = sparse_crc32(*crc32, copybuf, chunk); len -= chunk; } } return 0; }
static int process_raw_chunk(struct sparse_file *s, unsigned int chunk_size, int fd, int64_t offset, unsigned int blocks, unsigned int block, uint32_t *crc32) { int ret; int chunk; unsigned int len = blocks * s->block_size; if (chunk_size % s->block_size != 0) { return -EINVAL; } if (chunk_size / s->block_size != blocks) { return -EINVAL; } ret = sparse_file_add_fd(s, fd, offset, len, block); if (ret < 0) { return ret; } if (crc32) { while (len) { chunk = min(len, COPY_BUF_SIZE); ret = read_all(fd, copybuf, chunk); if (ret < 0) { return ret; } *crc32 = sparse_crc32(*crc32, copybuf, chunk); len -= chunk; } } else { lseek64(fd, len, SEEK_CUR); } return 0; }
int GetCrc32(uint32_t* crc32, int64_t len) override { *crc32 = sparse_crc32(*crc32, buf, len); Seek(len); return 0; }