diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-08-15 21:46:35 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-08-15 21:46:35 +0000 |
commit | 502af2167f7c218366666ca4944bd7cc54b5b19a (patch) | |
tree | a91fec5cc9769d260640bd91c6633cb9cf395524 /src/fs/fs_directory.c | |
parent | 03af5a603b7cc53432249d5854cd412aa90dde0d (diff) | |
download | gnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.tar.gz gnunet-502af2167f7c218366666ca4944bd7cc54b5b19a.zip |
indentation
Diffstat (limited to 'src/fs/fs_directory.c')
-rw-r--r-- | src/fs/fs_directory.c | 551 |
1 files changed, 259 insertions, 292 deletions
diff --git a/src/fs/fs_directory.c b/src/fs/fs_directory.c index dbd10c35e..f22480d5f 100644 --- a/src/fs/fs_directory.c +++ b/src/fs/fs_directory.c | |||
@@ -50,20 +50,22 @@ | |||
50 | * @return GNUNET_YES if it is, GNUNET_NO if it is not, GNUNET_SYSERR if | 50 | * @return GNUNET_YES if it is, GNUNET_NO if it is not, GNUNET_SYSERR if |
51 | * we have no mime-type information (treat as 'GNUNET_NO') | 51 | * we have no mime-type information (treat as 'GNUNET_NO') |
52 | */ | 52 | */ |
53 | int | 53 | int |
54 | GNUNET_FS_meta_data_test_for_directory (const struct GNUNET_CONTAINER_MetaData *md) | 54 | GNUNET_FS_meta_data_test_for_directory (const struct GNUNET_CONTAINER_MetaData |
55 | *md) | ||
55 | { | 56 | { |
56 | char *mime; | 57 | char *mime; |
57 | int ret; | 58 | int ret; |
58 | 59 | ||
59 | if (NULL == md) | 60 | if (NULL == md) |
60 | return GNUNET_SYSERR; | 61 | return GNUNET_SYSERR; |
61 | mime = GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_MIMETYPE); | 62 | mime = |
63 | GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_MIMETYPE); | ||
62 | if (mime == NULL) | 64 | if (mime == NULL) |
63 | return GNUNET_SYSERR; | 65 | return GNUNET_SYSERR; |
64 | ret = (0 == strcmp (mime, GNUNET_FS_DIRECTORY_MIME)) ? GNUNET_YES : GNUNET_NO; | 66 | ret = (0 == strcmp (mime, GNUNET_FS_DIRECTORY_MIME)) ? GNUNET_YES : GNUNET_NO; |
65 | GNUNET_free (mime); | 67 | GNUNET_free (mime); |
66 | return ret; | 68 | return ret; |
67 | } | 69 | } |
68 | 70 | ||
69 | 71 | ||
@@ -77,29 +79,29 @@ void | |||
77 | GNUNET_FS_meta_data_make_directory (struct GNUNET_CONTAINER_MetaData *md) | 79 | GNUNET_FS_meta_data_make_directory (struct GNUNET_CONTAINER_MetaData *md) |
78 | { | 80 | { |
79 | char *mime; | 81 | char *mime; |
80 | 82 | ||
81 | mime = GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_MIMETYPE); | 83 | mime = |
84 | GNUNET_CONTAINER_meta_data_get_by_type (md, EXTRACTOR_METATYPE_MIMETYPE); | ||
82 | if (mime != NULL) | 85 | if (mime != NULL) |
83 | { | 86 | { |
84 | GNUNET_break (0 == strcmp (mime, | 87 | GNUNET_break (0 == strcmp (mime, GNUNET_FS_DIRECTORY_MIME)); |
85 | GNUNET_FS_DIRECTORY_MIME)); | 88 | GNUNET_free (mime); |
86 | GNUNET_free (mime); | 89 | return; |
87 | return; | 90 | } |
88 | } | 91 | GNUNET_CONTAINER_meta_data_insert (md, |
89 | GNUNET_CONTAINER_meta_data_insert (md, | 92 | "<gnunet>", |
90 | "<gnunet>", | 93 | EXTRACTOR_METATYPE_MIMETYPE, |
91 | EXTRACTOR_METATYPE_MIMETYPE, | 94 | EXTRACTOR_METAFORMAT_UTF8, |
92 | EXTRACTOR_METAFORMAT_UTF8, | 95 | "text/plain", |
93 | "text/plain", | 96 | GNUNET_FS_DIRECTORY_MIME, |
94 | GNUNET_FS_DIRECTORY_MIME, | 97 | strlen (GNUNET_FS_DIRECTORY_MIME) + 1); |
95 | strlen (GNUNET_FS_DIRECTORY_MIME)+1); | ||
96 | } | 98 | } |
97 | 99 | ||
98 | 100 | ||
99 | /** | 101 | /** |
100 | * Closure for 'find_full_data'. | 102 | * Closure for 'find_full_data'. |
101 | */ | 103 | */ |
102 | struct GetFullDataClosure | 104 | struct GetFullDataClosure |
103 | { | 105 | { |
104 | 106 | ||
105 | /** | 107 | /** |
@@ -130,30 +132,26 @@ struct GetFullDataClosure | |||
130 | * @param data actual meta-data found | 132 | * @param data actual meta-data found |
131 | * @param data_len number of bytes in data | 133 | * @param data_len number of bytes in data |
132 | * @return 0 to continue extracting, 1 to abort | 134 | * @return 0 to continue extracting, 1 to abort |
133 | */ | 135 | */ |
134 | static int | 136 | static int |
135 | find_full_data (void *cls, | 137 | find_full_data (void *cls, |
136 | const char *plugin_name, | 138 | const char *plugin_name, |
137 | enum EXTRACTOR_MetaType type, | 139 | enum EXTRACTOR_MetaType type, |
138 | enum EXTRACTOR_MetaFormat format, | 140 | enum EXTRACTOR_MetaFormat format, |
139 | const char *data_mime_type, | 141 | const char *data_mime_type, const char *data, size_t data_len) |
140 | const char *data, | ||
141 | size_t data_len) | ||
142 | { | 142 | { |
143 | struct GetFullDataClosure *gfdc = cls; | 143 | struct GetFullDataClosure *gfdc = cls; |
144 | 144 | ||
145 | if (type == EXTRACTOR_METATYPE_GNUNET_FULL_DATA) | 145 | if (type == EXTRACTOR_METATYPE_GNUNET_FULL_DATA) |
146 | { | ||
147 | gfdc->size = data_len; | ||
148 | if (data_len > 0) | ||
146 | { | 149 | { |
147 | gfdc->size = data_len; | 150 | gfdc->data = GNUNET_malloc (data_len); |
148 | if (data_len > 0) | 151 | memcpy (gfdc->data, data, data_len); |
149 | { | ||
150 | gfdc->data = GNUNET_malloc (data_len); | ||
151 | memcpy (gfdc->data, | ||
152 | data, | ||
153 | data_len); | ||
154 | } | ||
155 | return 1; | ||
156 | } | 152 | } |
153 | return 1; | ||
154 | } | ||
157 | return 0; | 155 | return 0; |
158 | } | 156 | } |
159 | 157 | ||
@@ -183,12 +181,12 @@ find_full_data (void *cls, | |||
183 | * GNUNET_NO if this could be part of a directory (but not 100% OK) | 181 | * GNUNET_NO if this could be part of a directory (but not 100% OK) |
184 | * GNUNET_SYSERR if 'data' does not represent a directory | 182 | * GNUNET_SYSERR if 'data' does not represent a directory |
185 | */ | 183 | */ |
186 | int | 184 | int |
187 | GNUNET_FS_directory_list_contents (size_t size, | 185 | GNUNET_FS_directory_list_contents (size_t size, |
188 | const void *data, | 186 | const void *data, |
189 | uint64_t offset, | 187 | uint64_t offset, |
190 | GNUNET_FS_DirectoryEntryProcessor dep, | 188 | GNUNET_FS_DirectoryEntryProcessor dep, |
191 | void *dep_cls) | 189 | void *dep_cls) |
192 | { | 190 | { |
193 | struct GetFullDataClosure full_data; | 191 | struct GetFullDataClosure full_data; |
194 | const char *cdata = data; | 192 | const char *cdata = data; |
@@ -201,123 +199,110 @@ GNUNET_FS_directory_list_contents (size_t size, | |||
201 | struct GNUNET_CONTAINER_MetaData *md; | 199 | struct GNUNET_CONTAINER_MetaData *md; |
202 | char *filename; | 200 | char *filename; |
203 | 201 | ||
204 | if ( (offset == 0) && | 202 | if ((offset == 0) && |
205 | ( (size < 8 + sizeof (uint32_t)) || | 203 | ((size < 8 + sizeof (uint32_t)) || |
206 | (0 != memcmp (cdata, GNUNET_FS_DIRECTORY_MAGIC, 8)) ) ) | 204 | (0 != memcmp (cdata, GNUNET_FS_DIRECTORY_MAGIC, 8)))) |
205 | { | ||
206 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
207 | _("MAGIC mismatch. This is not a GNUnet directory.\n")); | ||
208 | return GNUNET_SYSERR; | ||
209 | } | ||
210 | pos = offset; | ||
211 | if (offset == 0) | ||
212 | { | ||
213 | memcpy (&mdSize, &cdata[8], sizeof (uint32_t)); | ||
214 | mdSize = ntohl (mdSize); | ||
215 | if (mdSize > size - 8 - sizeof (uint32_t)) | ||
207 | { | 216 | { |
217 | /* invalid size */ | ||
208 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 218 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
209 | _("MAGIC mismatch. This is not a GNUnet directory.\n")); | 219 | _("MAGIC mismatch. This is not a GNUnet directory.\n")); |
210 | return GNUNET_SYSERR; | 220 | return GNUNET_SYSERR; |
211 | } | 221 | } |
212 | pos = offset; | 222 | md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[8 + |
213 | if (offset == 0) | 223 | sizeof (uint32_t)], |
224 | mdSize); | ||
225 | if (md == NULL) | ||
214 | { | 226 | { |
215 | memcpy (&mdSize, &cdata[8], sizeof (uint32_t)); | 227 | GNUNET_break (0); |
216 | mdSize = ntohl (mdSize); | 228 | return GNUNET_SYSERR; /* malformed ! */ |
217 | if (mdSize > size - 8 - sizeof (uint32_t)) | ||
218 | { | ||
219 | /* invalid size */ | ||
220 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
221 | _("MAGIC mismatch. This is not a GNUnet directory.\n")); | ||
222 | return GNUNET_SYSERR; | ||
223 | } | ||
224 | md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[8 + | ||
225 | sizeof (uint32_t)], | ||
226 | mdSize); | ||
227 | if (md == NULL) | ||
228 | { | ||
229 | GNUNET_break (0); | ||
230 | return GNUNET_SYSERR; /* malformed ! */ | ||
231 | } | ||
232 | dep (dep_cls, | ||
233 | NULL, | ||
234 | NULL, | ||
235 | md, | ||
236 | 0, | ||
237 | NULL); | ||
238 | GNUNET_CONTAINER_meta_data_destroy (md); | ||
239 | pos = 8 + sizeof (uint32_t) + mdSize; | ||
240 | } | 229 | } |
230 | dep (dep_cls, NULL, NULL, md, 0, NULL); | ||
231 | GNUNET_CONTAINER_meta_data_destroy (md); | ||
232 | pos = 8 + sizeof (uint32_t) + mdSize; | ||
233 | } | ||
241 | while (pos < size) | 234 | while (pos < size) |
235 | { | ||
236 | /* find end of URI */ | ||
237 | if (cdata[pos] == '\0') | ||
242 | { | 238 | { |
243 | /* find end of URI */ | 239 | /* URI is never empty, must be end of block, |
244 | if (cdata[pos] == '\0') | 240 | * skip to next alignment */ |
245 | { | 241 | align = ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE; |
246 | /* URI is never empty, must be end of block, | 242 | if (align == pos) |
247 | skip to next alignment */ | 243 | { |
248 | align = | 244 | /* if we were already aligned, still skip a block! */ |
249 | ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE; | 245 | align += DBLOCK_SIZE; |
250 | if (align == pos) | 246 | } |
251 | { | 247 | pos = align; |
252 | /* if we were already aligned, still skip a block! */ | 248 | if (pos >= size) |
253 | align += DBLOCK_SIZE; | 249 | { |
254 | } | 250 | /* malformed - or partial download... */ |
255 | pos = align; | 251 | break; |
256 | if (pos >= size) | 252 | } |
257 | { | 253 | } |
258 | /* malformed - or partial download... */ | 254 | epos = pos; |
259 | break; | 255 | while ((epos < size) && (cdata[epos] != '\0')) |
260 | } | 256 | epos++; |
261 | } | 257 | if (epos >= size) |
262 | epos = pos; | 258 | return GNUNET_NO; /* malformed - or partial download */ |
263 | while ((epos < size) && (cdata[epos] != '\0')) | 259 | |
264 | epos++; | 260 | uri = GNUNET_FS_uri_parse (&cdata[pos], &emsg); |
265 | if (epos >= size) | 261 | pos = epos + 1; |
266 | return GNUNET_NO; /* malformed - or partial download */ | 262 | if (uri == NULL) |
267 | 263 | { | |
268 | uri = GNUNET_FS_uri_parse (&cdata[pos], &emsg); | 264 | GNUNET_free (emsg); |
269 | pos = epos + 1; | 265 | pos--; /* go back to '\0' to force going to next alignment */ |
270 | if (uri == NULL) | 266 | continue; |
271 | { | 267 | } |
272 | GNUNET_free (emsg); | 268 | if (GNUNET_FS_uri_test_ksk (uri)) |
273 | pos--; /* go back to '\0' to force going to next alignment */ | 269 | { |
274 | continue; | 270 | GNUNET_FS_uri_destroy (uri); |
275 | } | 271 | GNUNET_break (0); |
276 | if (GNUNET_FS_uri_test_ksk (uri)) | 272 | return GNUNET_NO; /* illegal in directory! */ |
277 | { | 273 | } |
278 | GNUNET_FS_uri_destroy (uri); | ||
279 | GNUNET_break (0); | ||
280 | return GNUNET_NO; /* illegal in directory! */ | ||
281 | } | ||
282 | 274 | ||
283 | memcpy (&mdSize, &cdata[pos], sizeof (uint32_t)); | 275 | memcpy (&mdSize, &cdata[pos], sizeof (uint32_t)); |
284 | mdSize = ntohl (mdSize); | 276 | mdSize = ntohl (mdSize); |
285 | pos += sizeof (uint32_t); | 277 | pos += sizeof (uint32_t); |
286 | if (pos + mdSize > size) | 278 | if (pos + mdSize > size) |
287 | { | 279 | { |
288 | GNUNET_FS_uri_destroy (uri); | 280 | GNUNET_FS_uri_destroy (uri); |
289 | return GNUNET_NO; /* malformed - or partial download */ | 281 | return GNUNET_NO; /* malformed - or partial download */ |
290 | } | 282 | } |
291 | 283 | ||
292 | md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[pos], mdSize); | 284 | md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[pos], mdSize); |
293 | if (md == NULL) | 285 | if (md == NULL) |
294 | { | 286 | { |
295 | GNUNET_FS_uri_destroy (uri); | ||
296 | GNUNET_break (0); | ||
297 | return GNUNET_NO; /* malformed ! */ | ||
298 | } | ||
299 | pos += mdSize; | ||
300 | filename = GNUNET_CONTAINER_meta_data_get_by_type (md, | ||
301 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME); | ||
302 | full_data.size = 0; | ||
303 | full_data.data = NULL; | ||
304 | GNUNET_CONTAINER_meta_data_iterate (md, | ||
305 | &find_full_data, | ||
306 | &full_data); | ||
307 | if (dep != NULL) | ||
308 | { | ||
309 | dep (dep_cls, | ||
310 | filename, | ||
311 | uri, | ||
312 | md, | ||
313 | full_data.size, | ||
314 | full_data.data); | ||
315 | } | ||
316 | GNUNET_free_non_null (full_data.data); | ||
317 | GNUNET_free_non_null (filename); | ||
318 | GNUNET_CONTAINER_meta_data_destroy (md); | ||
319 | GNUNET_FS_uri_destroy (uri); | 287 | GNUNET_FS_uri_destroy (uri); |
288 | GNUNET_break (0); | ||
289 | return GNUNET_NO; /* malformed ! */ | ||
320 | } | 290 | } |
291 | pos += mdSize; | ||
292 | filename = GNUNET_CONTAINER_meta_data_get_by_type (md, | ||
293 | EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME); | ||
294 | full_data.size = 0; | ||
295 | full_data.data = NULL; | ||
296 | GNUNET_CONTAINER_meta_data_iterate (md, &find_full_data, &full_data); | ||
297 | if (dep != NULL) | ||
298 | { | ||
299 | dep (dep_cls, filename, uri, md, full_data.size, full_data.data); | ||
300 | } | ||
301 | GNUNET_free_non_null (full_data.data); | ||
302 | GNUNET_free_non_null (filename); | ||
303 | GNUNET_CONTAINER_meta_data_destroy (md); | ||
304 | GNUNET_FS_uri_destroy (uri); | ||
305 | } | ||
321 | return GNUNET_OK; | 306 | return GNUNET_OK; |
322 | } | 307 | } |
323 | 308 | ||
@@ -330,7 +315,7 @@ struct BuilderEntry | |||
330 | * This is a linked list. | 315 | * This is a linked list. |
331 | */ | 316 | */ |
332 | struct BuilderEntry *next; | 317 | struct BuilderEntry *next; |
333 | 318 | ||
334 | /** | 319 | /** |
335 | * Length of this entry. | 320 | * Length of this entry. |
336 | */ | 321 | */ |
@@ -365,11 +350,12 @@ struct GNUNET_FS_DirectoryBuilder | |||
365 | * @param mdir metadata for the directory | 350 | * @param mdir metadata for the directory |
366 | */ | 351 | */ |
367 | struct GNUNET_FS_DirectoryBuilder * | 352 | struct GNUNET_FS_DirectoryBuilder * |
368 | GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData *mdir) | 353 | GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData |
354 | *mdir) | ||
369 | { | 355 | { |
370 | struct GNUNET_FS_DirectoryBuilder *ret; | 356 | struct GNUNET_FS_DirectoryBuilder *ret; |
371 | 357 | ||
372 | ret = GNUNET_malloc(sizeof(struct GNUNET_FS_DirectoryBuilder)); | 358 | ret = GNUNET_malloc (sizeof (struct GNUNET_FS_DirectoryBuilder)); |
373 | if (mdir != NULL) | 359 | if (mdir != NULL) |
374 | ret->meta = GNUNET_CONTAINER_meta_data_duplicate (mdir); | 360 | ret->meta = GNUNET_CONTAINER_meta_data_duplicate (mdir); |
375 | else | 361 | else |
@@ -391,9 +377,9 @@ GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData *mdir | |||
391 | */ | 377 | */ |
392 | void | 378 | void |
393 | GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld, | 379 | GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld, |
394 | const struct GNUNET_FS_Uri *uri, | 380 | const struct GNUNET_FS_Uri *uri, |
395 | const struct GNUNET_CONTAINER_MetaData *md, | 381 | const struct GNUNET_CONTAINER_MetaData *md, |
396 | const void *data) | 382 | const void *data) |
397 | { | 383 | { |
398 | struct GNUNET_FS_Uri *curi; | 384 | struct GNUNET_FS_Uri *curi; |
399 | struct BuilderEntry *e; | 385 | struct BuilderEntry *e; |
@@ -409,68 +395,64 @@ GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld, | |||
409 | struct GNUNET_CONTAINER_MetaData *meta; | 395 | struct GNUNET_CONTAINER_MetaData *meta; |
410 | const struct GNUNET_CONTAINER_MetaData *meta_use; | 396 | const struct GNUNET_CONTAINER_MetaData *meta_use; |
411 | 397 | ||
412 | GNUNET_assert (! GNUNET_FS_uri_test_ksk (uri)); | 398 | GNUNET_assert (!GNUNET_FS_uri_test_ksk (uri)); |
413 | if (NULL != data) | 399 | if (NULL != data) |
400 | { | ||
401 | GNUNET_assert (!GNUNET_FS_uri_test_sks (uri)); | ||
402 | if (GNUNET_FS_uri_test_chk (uri)) | ||
414 | { | 403 | { |
415 | GNUNET_assert (! GNUNET_FS_uri_test_sks (uri)); | 404 | fsize = GNUNET_FS_uri_chk_get_file_size (uri); |
416 | if (GNUNET_FS_uri_test_chk (uri)) | ||
417 | { | ||
418 | fsize = GNUNET_FS_uri_chk_get_file_size (uri); | ||
419 | } | ||
420 | else | ||
421 | { | ||
422 | curi = GNUNET_FS_uri_loc_get_uri (uri); | ||
423 | GNUNET_assert (NULL != curi); | ||
424 | fsize = GNUNET_FS_uri_chk_get_file_size (curi); | ||
425 | GNUNET_FS_uri_destroy (curi); | ||
426 | } | ||
427 | } | 405 | } |
428 | else | 406 | else |
429 | { | 407 | { |
430 | fsize = 0; /* not given */ | 408 | curi = GNUNET_FS_uri_loc_get_uri (uri); |
409 | GNUNET_assert (NULL != curi); | ||
410 | fsize = GNUNET_FS_uri_chk_get_file_size (curi); | ||
411 | GNUNET_FS_uri_destroy (curi); | ||
431 | } | 412 | } |
413 | } | ||
414 | else | ||
415 | { | ||
416 | fsize = 0; /* not given */ | ||
417 | } | ||
432 | if (fsize > MAX_INLINE_SIZE) | 418 | if (fsize > MAX_INLINE_SIZE) |
433 | fsize = 0; /* too large */ | 419 | fsize = 0; /* too large */ |
434 | uris = GNUNET_FS_uri_to_string (uri); | 420 | uris = GNUNET_FS_uri_to_string (uri); |
435 | slen = strlen (uris) + 1; | 421 | slen = strlen (uris) + 1; |
436 | mds = | 422 | mds = GNUNET_CONTAINER_meta_data_get_serialized_size (md); |
437 | GNUNET_CONTAINER_meta_data_get_serialized_size (md); | ||
438 | meta_use = md; | 423 | meta_use = md; |
439 | meta = NULL; | 424 | meta = NULL; |
440 | if (fsize > 0) | 425 | if (fsize > 0) |
426 | { | ||
427 | meta = GNUNET_CONTAINER_meta_data_duplicate (md); | ||
428 | GNUNET_CONTAINER_meta_data_insert (meta, | ||
429 | "<gnunet>", | ||
430 | EXTRACTOR_METATYPE_GNUNET_FULL_DATA, | ||
431 | EXTRACTOR_METAFORMAT_BINARY, | ||
432 | NULL, data, fsize); | ||
433 | mdxs = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); | ||
434 | if ((slen + sizeof (uint32_t) + mdxs - 1) / DBLOCK_SIZE == | ||
435 | (slen + sizeof (uint32_t) + mds - 1) / DBLOCK_SIZE) | ||
441 | { | 436 | { |
442 | meta = GNUNET_CONTAINER_meta_data_duplicate (md); | 437 | /* adding full data would not cause us to cross |
443 | GNUNET_CONTAINER_meta_data_insert (meta, | 438 | * additional blocks, so add it! */ |
444 | "<gnunet>", | 439 | meta_use = meta; |
445 | EXTRACTOR_METATYPE_GNUNET_FULL_DATA, | 440 | mds = mdxs; |
446 | EXTRACTOR_METAFORMAT_BINARY, | ||
447 | NULL, | ||
448 | data, | ||
449 | fsize); | ||
450 | mdxs = | ||
451 | GNUNET_CONTAINER_meta_data_get_serialized_size (meta); | ||
452 | if ( (slen + sizeof (uint32_t) + mdxs - 1) / DBLOCK_SIZE == | ||
453 | (slen + sizeof (uint32_t) + mds - 1) / DBLOCK_SIZE) | ||
454 | { | ||
455 | /* adding full data would not cause us to cross | ||
456 | additional blocks, so add it! */ | ||
457 | meta_use = meta; | ||
458 | mds = mdxs; | ||
459 | } | ||
460 | } | 441 | } |
442 | } | ||
461 | 443 | ||
462 | if (mds > GNUNET_MAX_MALLOC_CHECKED / 2) | 444 | if (mds > GNUNET_MAX_MALLOC_CHECKED / 2) |
463 | mds = GNUNET_MAX_MALLOC_CHECKED / 2; | 445 | mds = GNUNET_MAX_MALLOC_CHECKED / 2; |
464 | e = GNUNET_malloc (sizeof(struct BuilderEntry) + | 446 | e = GNUNET_malloc (sizeof (struct BuilderEntry) + |
465 | slen + mds + sizeof (uint32_t)); | 447 | slen + mds + sizeof (uint32_t)); |
466 | ser = (char*) &e[1]; | 448 | ser = (char *) &e[1]; |
467 | memcpy (ser, uris, slen); | 449 | memcpy (ser, uris, slen); |
468 | GNUNET_free (uris); | 450 | GNUNET_free (uris); |
469 | sptr = &ser[slen + sizeof(uint32_t)]; | 451 | sptr = &ser[slen + sizeof (uint32_t)]; |
470 | ret = GNUNET_CONTAINER_meta_data_serialize (meta_use, | 452 | ret = GNUNET_CONTAINER_meta_data_serialize (meta_use, |
471 | &sptr, | 453 | &sptr, |
472 | mds, | 454 | mds, |
473 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); | 455 | GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); |
474 | if (NULL != meta) | 456 | if (NULL != meta) |
475 | GNUNET_CONTAINER_meta_data_destroy (meta); | 457 | GNUNET_CONTAINER_meta_data_destroy (meta); |
476 | if (ret == -1) | 458 | if (ret == -1) |
@@ -492,11 +474,10 @@ GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld, | |||
492 | * after alignment to the DBLOCK_SIZE. | 474 | * after alignment to the DBLOCK_SIZE. |
493 | */ | 475 | */ |
494 | static size_t | 476 | static size_t |
495 | do_align (size_t start_position, | 477 | do_align (size_t start_position, size_t end_position) |
496 | size_t end_position) | ||
497 | { | 478 | { |
498 | size_t align; | 479 | size_t align; |
499 | 480 | ||
500 | align = (end_position / DBLOCK_SIZE) * DBLOCK_SIZE; | 481 | align = (end_position / DBLOCK_SIZE) * DBLOCK_SIZE; |
501 | if ((start_position < align) && (end_position > align)) | 482 | if ((start_position < align) && (end_position > align)) |
502 | return align + end_position - start_position; | 483 | return align + end_position - start_position; |
@@ -515,9 +496,7 @@ do_align (size_t start_position, | |||
515 | */ | 496 | */ |
516 | static void | 497 | static void |
517 | block_align (size_t start, | 498 | block_align (size_t start, |
518 | unsigned int count, | 499 | unsigned int count, const size_t * sizes, unsigned int *perm) |
519 | const size_t *sizes, | ||
520 | unsigned int *perm) | ||
521 | { | 500 | { |
522 | unsigned int i; | 501 | unsigned int i; |
523 | unsigned int j; | 502 | unsigned int j; |
@@ -531,51 +510,46 @@ block_align (size_t start, | |||
531 | 510 | ||
532 | cpos = start; | 511 | cpos = start; |
533 | for (i = 0; i < count; i++) | 512 | for (i = 0; i < count; i++) |
513 | { | ||
514 | start = cpos; | ||
515 | badness = 0x7FFFFFFF; | ||
516 | best = -1; | ||
517 | for (j = i; j < count; j++) | ||
534 | { | 518 | { |
535 | start = cpos; | 519 | cval = perm[j]; |
536 | badness = 0x7FFFFFFF; | 520 | cend = cpos + sizes[cval]; |
537 | best = -1; | 521 | if (cpos % DBLOCK_SIZE == 0) |
538 | for (j = i; j < count; j++) | 522 | { |
523 | /* prefer placing the largest blocks first */ | ||
524 | cbad = -(cend % DBLOCK_SIZE); | ||
525 | } | ||
526 | else | ||
527 | { | ||
528 | if (cpos / DBLOCK_SIZE == cend / DBLOCK_SIZE) | ||
529 | { | ||
530 | /* Data fits into the same block! Prefer small left-overs! */ | ||
531 | cbad = DBLOCK_SIZE - cend % DBLOCK_SIZE; | ||
532 | } | ||
533 | else | ||
539 | { | 534 | { |
540 | cval = perm[j]; | 535 | /* Would have to waste space to re-align, add big factor, this |
541 | cend = cpos + sizes[cval]; | 536 | * case is a real loss (proportional to space wasted)! */ |
542 | if (cpos % DBLOCK_SIZE == 0) | 537 | cbad = DBLOCK_SIZE * (DBLOCK_SIZE - cpos % DBLOCK_SIZE); |
543 | { | ||
544 | /* prefer placing the largest blocks first */ | ||
545 | cbad = -(cend % DBLOCK_SIZE); | ||
546 | } | ||
547 | else | ||
548 | { | ||
549 | if (cpos / DBLOCK_SIZE == | ||
550 | cend / DBLOCK_SIZE) | ||
551 | { | ||
552 | /* Data fits into the same block! Prefer small left-overs! */ | ||
553 | cbad = | ||
554 | DBLOCK_SIZE - cend % DBLOCK_SIZE; | ||
555 | } | ||
556 | else | ||
557 | { | ||
558 | /* Would have to waste space to re-align, add big factor, this | ||
559 | case is a real loss (proportional to space wasted)! */ | ||
560 | cbad = | ||
561 | DBLOCK_SIZE * (DBLOCK_SIZE - | ||
562 | cpos % | ||
563 | DBLOCK_SIZE); | ||
564 | } | ||
565 | } | ||
566 | if (cbad < badness) | ||
567 | { | ||
568 | best = j; | ||
569 | badness = cbad; | ||
570 | } | ||
571 | } | 538 | } |
572 | GNUNET_assert (best != -1); | 539 | } |
573 | tmp = perm[i]; | 540 | if (cbad < badness) |
574 | perm[i] = perm[best]; | 541 | { |
575 | perm[best] = tmp; | 542 | best = j; |
576 | cpos += sizes[perm[i]]; | 543 | badness = cbad; |
577 | cpos = do_align (start, cpos); | 544 | } |
578 | } | 545 | } |
546 | GNUNET_assert (best != -1); | ||
547 | tmp = perm[i]; | ||
548 | perm[i] = perm[best]; | ||
549 | perm[best] = tmp; | ||
550 | cpos += sizes[perm[i]]; | ||
551 | cpos = do_align (start, cpos); | ||
552 | } | ||
579 | } | 553 | } |
580 | 554 | ||
581 | 555 | ||
@@ -591,8 +565,7 @@ block_align (size_t start, | |||
591 | */ | 565 | */ |
592 | int | 566 | int |
593 | GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld, | 567 | GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld, |
594 | size_t *rsize, | 568 | size_t * rsize, void **rdata) |
595 | void **rdata) | ||
596 | { | 569 | { |
597 | char *data; | 570 | char *data; |
598 | char *sptr; | 571 | char *sptr; |
@@ -614,71 +587,65 @@ GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld, | |||
614 | perm = NULL; | 587 | perm = NULL; |
615 | bes = NULL; | 588 | bes = NULL; |
616 | if (0 < bld->count) | 589 | if (0 < bld->count) |
590 | { | ||
591 | sizes = GNUNET_malloc (bld->count * sizeof (size_t)); | ||
592 | perm = GNUNET_malloc (bld->count * sizeof (unsigned int)); | ||
593 | bes = GNUNET_malloc (bld->count * sizeof (struct BuilderEntry *)); | ||
594 | pos = bld->head; | ||
595 | for (i = 0; i < bld->count; i++) | ||
596 | { | ||
597 | perm[i] = i; | ||
598 | bes[i] = pos; | ||
599 | sizes[i] = pos->len; | ||
600 | pos = pos->next; | ||
601 | } | ||
602 | block_align (size, bld->count, sizes, perm); | ||
603 | /* compute final size with alignment */ | ||
604 | for (i = 0; i < bld->count; i++) | ||
617 | { | 605 | { |
618 | sizes = GNUNET_malloc (bld->count * sizeof (size_t)); | 606 | psize = size; |
619 | perm = GNUNET_malloc (bld->count * sizeof (unsigned int)); | 607 | size += sizes[perm[i]]; |
620 | bes = GNUNET_malloc (bld->count * sizeof (struct BuilderEntry *)); | 608 | size = do_align (psize, size); |
621 | pos = bld->head; | ||
622 | for (i = 0; i < bld->count; i++) | ||
623 | { | ||
624 | perm[i] = i; | ||
625 | bes[i] = pos; | ||
626 | sizes[i] = pos->len; | ||
627 | pos = pos->next; | ||
628 | } | ||
629 | block_align (size, | ||
630 | bld->count, | ||
631 | sizes, | ||
632 | perm); | ||
633 | /* compute final size with alignment */ | ||
634 | for (i = 0; i < bld->count; i++) | ||
635 | { | ||
636 | psize = size; | ||
637 | size += sizes[perm[i]]; | ||
638 | size = do_align (psize, size); | ||
639 | } | ||
640 | } | 609 | } |
610 | } | ||
641 | *rsize = size; | 611 | *rsize = size; |
642 | data = GNUNET_malloc_large (size); | 612 | data = GNUNET_malloc_large (size); |
643 | if (data == NULL) | 613 | if (data == NULL) |
644 | { | 614 | { |
645 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, | 615 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "malloc"); |
646 | "malloc"); | 616 | *rsize = 0; |
647 | *rsize = 0; | 617 | *rdata = NULL; |
648 | *rdata = NULL; | 618 | GNUNET_free_non_null (sizes); |
649 | GNUNET_free_non_null (sizes); | 619 | GNUNET_free_non_null (perm); |
650 | GNUNET_free_non_null (perm); | 620 | GNUNET_free_non_null (bes); |
651 | GNUNET_free_non_null (bes); | 621 | return GNUNET_SYSERR; |
652 | return GNUNET_SYSERR; | 622 | } |
653 | } | ||
654 | *rdata = data; | 623 | *rdata = data; |
655 | memcpy (data, GNUNET_DIRECTORY_MAGIC, strlen (GNUNET_DIRECTORY_MAGIC)); | 624 | memcpy (data, GNUNET_DIRECTORY_MAGIC, strlen (GNUNET_DIRECTORY_MAGIC)); |
656 | off = strlen (GNUNET_DIRECTORY_MAGIC); | 625 | off = strlen (GNUNET_DIRECTORY_MAGIC); |
657 | 626 | ||
658 | sptr = &data[off + sizeof (uint32_t)]; | 627 | sptr = &data[off + sizeof (uint32_t)]; |
659 | ret = GNUNET_CONTAINER_meta_data_serialize (bld->meta, | 628 | ret = GNUNET_CONTAINER_meta_data_serialize (bld->meta, |
660 | &sptr, | 629 | &sptr, |
661 | size - off - sizeof (uint32_t), | 630 | size - off - sizeof (uint32_t), |
662 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); | 631 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); |
663 | GNUNET_assert (ret != -1); | 632 | GNUNET_assert (ret != -1); |
664 | big = htonl (ret); | 633 | big = htonl (ret); |
665 | memcpy (&data[off], &big, sizeof (uint32_t)); | 634 | memcpy (&data[off], &big, sizeof (uint32_t)); |
666 | off += sizeof (uint32_t) + ret; | 635 | off += sizeof (uint32_t) + ret; |
667 | for (j = 0; j < bld->count; j++) | 636 | for (j = 0; j < bld->count; j++) |
668 | { | 637 | { |
669 | i = perm[j]; | 638 | i = perm[j]; |
670 | psize = off; | 639 | psize = off; |
671 | off += sizes[i]; | 640 | off += sizes[i]; |
672 | off = do_align (psize, off); | 641 | off = do_align (psize, off); |
673 | memcpy (&data[off - sizes[i]], | 642 | memcpy (&data[off - sizes[i]], &(bes[i])[1], sizes[i]); |
674 | &(bes[i])[1], | 643 | GNUNET_free (bes[i]); |
675 | sizes[i]); | 644 | } |
676 | GNUNET_free (bes[i]); | ||
677 | } | ||
678 | GNUNET_free_non_null (sizes); | 645 | GNUNET_free_non_null (sizes); |
679 | GNUNET_free_non_null (perm); | 646 | GNUNET_free_non_null (perm); |
680 | GNUNET_free_non_null (bes); | 647 | GNUNET_free_non_null (bes); |
681 | GNUNET_assert (off == size); | 648 | GNUNET_assert (off == size); |
682 | GNUNET_CONTAINER_meta_data_destroy (bld->meta); | 649 | GNUNET_CONTAINER_meta_data_destroy (bld->meta); |
683 | GNUNET_free (bld); | 650 | GNUNET_free (bld); |
684 | return GNUNET_OK; | 651 | return GNUNET_OK; |