summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrien Schildknecht2016-11-30 13:49:47 -0600
committerAdrien Schildknecht2016-11-30 21:16:28 -0600
commita26a6bd6f36d29cdc959f746b495f79f74c7fad7 (patch)
treec7fc492b1924ca83bb3839cd5cc92404f0ca2282 /libsparse
parent59826ddee5462d1be93176e2dee660c46e413e52 (diff)
downloadplatform-system-core-a26a6bd6f36d29cdc959f746b495f79f74c7fad7.tar.gz
platform-system-core-a26a6bd6f36d29cdc959f746b495f79f74c7fad7.tar.xz
platform-system-core-a26a6bd6f36d29cdc959f746b495f79f74c7fad7.zip
libsparse: add a function to retrieve the data blocks
Test: m libsparse Change-Id: I04bd3912bb4364e591b064ec2aab782cf02f6bd7
Diffstat (limited to 'libsparse')
-rw-r--r--libsparse/include/sparse/sparse.h25
-rw-r--r--libsparse/sparse.c56
2 files changed, 81 insertions, 0 deletions
diff --git a/libsparse/include/sparse/sparse.h b/libsparse/include/sparse/sparse.h
index 42d4adb87..356f65fd0 100644
--- a/libsparse/include/sparse/sparse.h
+++ b/libsparse/include/sparse/sparse.h
@@ -176,6 +176,13 @@ int sparse_file_write(struct sparse_file *s, int fd, bool gz, bool sparse,
176int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc); 176int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc);
177 177
178/** 178/**
179 * sparse_file_block_size
180 *
181 * @s - sparse file cookie
182 */
183unsigned int sparse_file_block_size(struct sparse_file *s);
184
185/**
179 * sparse_file_callback - call a callback for blocks in sparse file 186 * sparse_file_callback - call a callback for blocks in sparse file
180 * 187 *
181 * @s - sparse file cookie 188 * @s - sparse file cookie
@@ -197,6 +204,24 @@ int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
197 int (*write)(void *priv, const void *data, int len), void *priv); 204 int (*write)(void *priv, const void *data, int len), void *priv);
198 205
199/** 206/**
207 * sparse_file_foreach_chunk - call a callback for data blocks in sparse file
208 *
209 * @s - sparse file cookie
210 * @sparse - write in the Android sparse file format
211 * @crc - append a crc chunk
212 * @write - function to call for each block
213 * @priv - value that will be passed as the first argument to write
214 *
215 * The function has the same behavior as 'sparse_file_callback', except it only
216 * iterates on blocks that contain data.
217 *
218 * Returns 0 on success, negative errno on error.
219 */
220int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
221 int (*write)(void *priv, const void *data, int len, unsigned int block,
222 unsigned int nr_blocks),
223 void *priv);
224/**
200 * sparse_file_read - read a file into a sparse file cookie 225 * sparse_file_read - read a file into a sparse file cookie
201 * 226 *
202 * @s - sparse file cookie 227 * @s - sparse file cookie
diff --git a/libsparse/sparse.c b/libsparse/sparse.c
index 311678a34..b17586066 100644
--- a/libsparse/sparse.c
+++ b/libsparse/sparse.c
@@ -199,6 +199,57 @@ int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
199 return ret; 199 return ret;
200} 200}
201 201
202struct chunk_data {
203 void *priv;
204 unsigned int block;
205 unsigned int nr_blocks;
206 int (*write)(void *priv, const void *data, int len, unsigned int block,
207 unsigned int nr_blocks);
208};
209
210static int foreach_chunk_write(void *priv, const void *data, int len)
211{
212 struct chunk_data *chk = priv;
213
214 return chk->write(chk->priv, data, len, chk->block, chk->nr_blocks);
215}
216
217int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
218 int (*write)(void *priv, const void *data, int len, unsigned int block,
219 unsigned int nr_blocks),
220 void *priv)
221{
222 int ret;
223 int chunks;
224 struct chunk_data chk;
225 struct output_file *out;
226 struct backed_block *bb;
227
228 chk.priv = priv;
229 chk.write = write;
230 chk.block = chk.nr_blocks = 0;
231 chunks = sparse_count_chunks(s);
232 out = output_file_open_callback(foreach_chunk_write, &chk,
233 s->block_size, s->len, false, sparse,
234 chunks, crc);
235
236 if (!out)
237 return -ENOMEM;
238
239 for (bb = backed_block_iter_new(s->backed_block_list); bb;
240 bb = backed_block_iter_next(bb)) {
241 chk.block = backed_block_block(bb);
242 chk.nr_blocks = (backed_block_len(bb) - 1) / s->block_size + 1;
243 ret = sparse_file_write_block(out, bb);
244 if (ret)
245 return ret;
246 }
247
248 output_file_close(out);
249
250 return ret;
251}
252
202static int out_counter_write(void *priv, const void *data __unused, int len) 253static int out_counter_write(void *priv, const void *data __unused, int len)
203{ 254{
204 int64_t *count = priv; 255 int64_t *count = priv;
@@ -230,6 +281,11 @@ int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc)
230 return count; 281 return count;
231} 282}
232 283
284unsigned int sparse_file_block_size(struct sparse_file *s)
285{
286 return s->block_size;
287}
288
233static struct backed_block *move_chunks_up_to_len(struct sparse_file *from, 289static struct backed_block *move_chunks_up_to_len(struct sparse_file *from,
234 struct sparse_file *to, unsigned int len) 290 struct sparse_file *to, unsigned int len)
235{ 291{