11
uint32_t id;
12
uint64_t size;
13
chunk_write_fn write_fn;
14
+
15
+ const void *start;
16
};
17
18
struct chunkfile {
90
91
return 0;
92
}
93
+
94
+int read_table_of_contents(struct chunkfile *cf,
95
+ const unsigned char *mfile,
96
+ size_t mfile_size,
97
+ uint64_t toc_offset,
98
+ int toc_length)
99
+{
100
+ uint32_t chunk_id;
101
+ const unsigned char *table_of_contents = mfile + toc_offset;
102
+
103
+ ALLOC_GROW(cf->chunks, toc_length, cf->chunks_alloc);
104
+
105
+ while (toc_length--) {
106
+ uint64_t chunk_offset, next_chunk_offset;
107
+
108
+ chunk_id = get_be32(table_of_contents);
109
+ chunk_offset = get_be64(table_of_contents + 4);
110
+
111
+ if (!chunk_id) {
112
+ error(_("terminating chunk id appears earlier than expected"));
113
+ return 1;
114
+ }
115
+
116
+ table_of_contents += CHUNK_TOC_ENTRY_SIZE;
117
+ next_chunk_offset = get_be64(table_of_contents + 4);
118
+
119
+ if (next_chunk_offset < chunk_offset ||
120
+ next_chunk_offset > mfile_size - the_hash_algo->rawsz) {
121
+ error(_("improper chunk offset(s) %"PRIx64" and %"PRIx64""),
122
+ chunk_offset, next_chunk_offset);
123
+ return -1;
124
+ }
125
+
126
+ cf->chunks[cf->chunks_nr].id = chunk_id;
127
+ cf->chunks[cf->chunks_nr].start = mfile + chunk_offset;
128
+ cf->chunks[cf->chunks_nr].size = next_chunk_offset - chunk_offset;
129
+ cf->chunks_nr++;
130
+ }
131
+
132
+ chunk_id = get_be32(table_of_contents);
133
+ if (chunk_id) {
134
+ error(_("final chunk has non-zero id %"PRIx32""), chunk_id);
135
+ return -1;
136
+ }
137
+
138
+ return 0;
139
+}
140
+
141
+static int pair_chunk_fn(const unsigned char *chunk_start,
142
+ size_t chunk_size,
143
+ void *data)
144
+{
145
+ const unsigned char **p = data;
146
+ *p = chunk_start;
147
+ return 0;
148
+}
149
+
150
+int pair_chunk(struct chunkfile *cf,
151
+ uint32_t chunk_id,
152
+ const unsigned char **p)
153
+{
154
+ return read_chunk(cf, chunk_id, pair_chunk_fn, p);
155
+}
156
+
157
+int read_chunk(struct chunkfile *cf,
158
+ uint32_t chunk_id,
159
+ chunk_read_fn fn,
160
+ void *data)
161
+{
162
+ int i;
163
+
164
+ for (i = 0; i < cf->chunks_nr; i++) {
165
+ if (cf->chunks[i].id == chunk_id)
166
+ return fn(cf->chunks[i].start, cf->chunks[i].size, data);
167
+ }
168
+
169
+ return CHUNK_NOT_FOUND;
170
+}