Mercurial > hg > dmlib
comparison tools/packed.c @ 1026:16e63811d0c2
Clean up the pack file node adding/extracting.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 01 Mar 2015 16:07:45 +0200 |
parents | b43885dd3d1a |
children | d29058e93799 |
comparison
equal
deleted
inserted
replaced
1025:b43885dd3d1a | 1026:16e63811d0c2 |
---|---|
253 return DMERR_OK; | 253 return DMERR_OK; |
254 } | 254 } |
255 | 255 |
256 | 256 |
257 int dmPackAddFile(DMPackFile * pack, const char *filename, | 257 int dmPackAddFile(DMPackFile * pack, const char *filename, |
258 BOOL doCompress, const Uint32 flags, DMPackEntry ** ppEntry) | 258 const Uint32 flags, const BOOL compress, int level, DMPackEntry ** ppEntry) |
259 { | 259 { |
260 z_stream zstr; | 260 z_stream zstr; |
261 off_t startOffs; | 261 Uint64 startOffs, outSize; |
262 unsigned int zstrSize; | 262 FILE *inFile = NULL, *tmpFile; |
263 FILE *inFile = NULL; | |
264 Uint8 *inBuffer = NULL, *outBuffer = NULL; | 263 Uint8 *inBuffer = NULL, *outBuffer = NULL; |
265 DMPackEntry entry, *node; | 264 DMPackEntry entry, *node; |
266 int zres, ret = DMERR_OK; | 265 int ret = DMERR_OK; |
267 BOOL zinit = FALSE; | 266 BOOL zinit = FALSE; |
268 | 267 |
269 *ppEntry = NULL; | 268 *ppEntry = NULL; |
270 | 269 |
271 if (pack == NULL) | 270 if (pack == NULL) |
273 | 272 |
274 if (pack->file == NULL) | 273 if (pack->file == NULL) |
275 return DMERR_FOPEN; | 274 return DMERR_FOPEN; |
276 | 275 |
277 // Compute starting offset | 276 // Compute starting offset |
277 outSize = 0; | |
278 startOffs = sizeof(DMPackFileHeader); | 278 startOffs = sizeof(DMPackFileHeader); |
279 node = pack->entries; | 279 node = pack->entries; |
280 while (node != NULL) | 280 while (node != NULL) |
281 { | 281 { |
282 startOffs += node->length; | 282 startOffs += node->length; |
298 ret = DMERR_MALLOC; | 298 ret = DMERR_MALLOC; |
299 goto out; | 299 goto out; |
300 } | 300 } |
301 | 301 |
302 // Read (and possibly compress) the data | 302 // Read (and possibly compress) the data |
303 zstrSize = 0; | 303 if (compress) |
304 zstr.zalloc = (alloc_func) Z_NULL; | 304 { |
305 zstr.zfree = (free_func) Z_NULL; | 305 int zret; |
306 zstr.opaque = (voidpf) Z_NULL; | 306 memset(&zstr, 0, sizeof(zstr)); |
307 zres = deflateInit(&zstr, doCompress ? Z_DEFAULT_COMPRESSION : 0); | 307 if (deflateInit(&zstr, level) != Z_OK) |
308 if (zres != Z_OK) | 308 { |
309 { | 309 ret = DMERR_COMPRESSION; |
310 ret = DMERR_COMPRESSION; | 310 goto out; |
311 goto out; | 311 } |
312 } | 312 zinit = TRUE; |
313 zinit = TRUE; | 313 |
314 | 314 tmpFile = fopen("dump.bin", "wb"); |
315 // Initialize compression streams | 315 |
316 zres = Z_OK; | 316 // Initialize compression streams |
317 while (!feof(inFile) && zres == Z_OK) | 317 zret = Z_OK; |
318 { | 318 while (!feof(inFile) && zret == Z_OK) |
319 zstr.avail_in = fread(inBuffer, sizeof(Uint8), SET_TMPBUF_SIZE, inFile); | 319 { |
320 zstr.next_in = inBuffer; | 320 zstr.avail_in = fread(inBuffer, sizeof(Uint8), SET_TMPBUF_SIZE, inFile); |
321 zstr.next_out = outBuffer; | 321 |
322 zstr.avail_out = SET_TMPBUF_SIZE; | 322 zstr.next_in = inBuffer; |
323 zstr.total_out = 0; | 323 zstr.next_out = outBuffer; |
324 zres = deflate(&zstr, Z_FULL_FLUSH); | 324 zstr.avail_out = SET_TMPBUF_SIZE; |
325 | 325 zstr.total_out = 0; |
326 if (zres == Z_OK && zstr.total_out > 0) | 326 zret = deflate(&zstr, Z_FULL_FLUSH); |
327 { | 327 |
328 zstrSize += zstr.total_out; | 328 if (zret == Z_OK && zstr.total_out > 0) |
329 if (fwrite(outBuffer, sizeof(Uint8), zstr.total_out, pack->file) != zstr.total_out) | 329 { |
330 { | 330 outSize += zstr.total_out; |
331 ret = DMERR_FWRITE; | 331 fwrite(outBuffer, sizeof(Uint8), zstr.total_out, tmpFile); |
332 goto out; | 332 if (fwrite(outBuffer, sizeof(Uint8), zstr.total_out, pack->file) != zstr.total_out) |
333 } | 333 { |
334 } | 334 ret = DMERR_FWRITE; |
335 goto out; | |
336 } | |
337 } | |
338 } | |
339 fclose(tmpFile); | |
335 } | 340 } |
336 | 341 |
337 // Create directory entry | 342 // Create directory entry |
338 strncpy(entry.filename, filename, sizeof(entry.filename)); | 343 strncpy(entry.filename, filename, sizeof(entry.filename)); |
339 entry.filename[sizeof(entry.filename) - 1] = 0; | 344 entry.filename[sizeof(entry.filename) - 1] = 0; |
340 entry.offset = startOffs; | 345 entry.offset = startOffs; |
341 entry.size = zstr.total_in; | 346 entry.size = zstr.total_in; |
342 entry.length = zstrSize; | 347 entry.length = outSize; |
343 entry.flags = flags; | 348 entry.flags = flags; |
344 | 349 |
345 // Add directory entry | 350 // Add directory entry |
346 if ((*ppEntry = dmPackEntryCopy(&entry)) == NULL) | 351 if ((*ppEntry = dmPackEntryCopy(&entry)) == NULL) |
347 { | 352 { |
366 | 371 |
367 | 372 |
368 /* | 373 /* |
369 * EXTRACT a file from the PACK | 374 * EXTRACT a file from the PACK |
370 */ | 375 */ |
371 int dmPackExtractFile(DMPackFile *pack, DMPackEntry * entry) | 376 int dmPackExtractFile(DMPackFile *pack, DMPackEntry * entry, BOOL decompress) |
372 { | 377 { |
373 z_stream zstr; | 378 z_stream zstr; |
374 FILE *outFile; | 379 FILE *outFile = NULL; |
375 Uint8 *inBuffer, *outBuffer; | 380 Uint8 *inBuffer = NULL, *outBuffer = NULL; |
376 size_t inDataLeft; | 381 size_t remaining; |
377 int ret; | 382 int zret, ret = DMERR_OK; |
383 BOOL zinit = FALSE; | |
378 | 384 |
379 if (pack == NULL) | 385 if (pack == NULL) |
380 return DMERR_NULLPTR; | 386 return DMERR_NULLPTR; |
381 | 387 |
382 if (pack->file == NULL) | 388 if (pack->file == NULL) |
383 return DMERR_FOPEN; | 389 return DMERR_FOPEN; |
384 | 390 |
385 // Seek to the position | 391 // Seek to the position |
386 if (fseek(pack->file, entry->offset, SEEK_SET) != 0) | 392 if (fseek(pack->file, entry->offset, SEEK_SET) != 0) |
387 return DMERR_INVALID; | 393 return DMERR_FSEEK; |
388 | 394 |
389 // Open destination file | 395 // Open destination file |
390 if ((outFile = fopen(entry->filename, "wb")) == NULL) | 396 if ((outFile = fopen(entry->filename, "wb")) == NULL) |
391 return -1; | 397 return DMERR_FOPEN; |
392 | 398 |
393 // Allocate temporary buffer | 399 // Allocate temporary buffer |
394 if ((inBuffer = (Uint8 *) dmMalloc(SET_TMPBUF_SIZE)) == NULL) | 400 if ((inBuffer = (Uint8 *) dmMalloc(SET_TMPBUF_SIZE)) == NULL || |
395 { | 401 (outBuffer = (Uint8 *) dmMalloc(SET_TMPBUF_SIZE)) == NULL) |
396 fclose(outFile); | 402 { |
397 return DMERR_MALLOC; | 403 ret = DMERR_MALLOC; |
398 } | 404 goto out; |
399 | 405 } |
400 if ((outBuffer = (Uint8 *) dmMalloc(SET_TMPBUF_SIZE)) == NULL) | 406 |
401 { | 407 // Read and uncompress the data, if needed |
402 dmFree(inBuffer); | 408 if (decompress || (entry->flags & DMF_COMPRESSED) == 0) |
403 fclose(outFile); | 409 { |
404 return DMERR_MALLOC; | 410 memset(&zstr, 0, sizeof(zstr)); |
405 } | 411 if (inflateInit(&zstr) != Z_OK) |
406 | 412 { |
407 // Read and uncompress the data | 413 ret = DMERR_COMPRESSION; |
408 zstr.zalloc = (alloc_func) Z_NULL; | 414 goto out; |
409 zstr.zfree = (free_func) Z_NULL; | 415 } |
410 zstr.opaque = (voidpf) Z_NULL; | 416 zinit = TRUE; |
411 ret = inflateInit(&zstr); | |
412 if (ret != Z_OK) | |
413 { | |
414 dmFree(inBuffer); | |
415 dmFree(outBuffer); | |
416 fclose(outFile); | |
417 return DMERR_COMPRESSION; | |
418 } | 417 } |
419 | 418 |
420 // Initialize compression streams | 419 // Initialize compression streams |
421 inDataLeft = entry->length; | 420 remaining = entry->length; |
422 ret = Z_OK; | 421 zret = Z_OK; |
423 while (inDataLeft > 0 && ret == Z_OK) | 422 while (remaining > 0 && zret == Z_OK) |
424 { | 423 { |
425 if (inDataLeft >= SET_TMPBUF_SIZE) | 424 size_t needed = remaining > SET_TMPBUF_SIZE ? SET_TMPBUF_SIZE : remaining; |
426 zstr.avail_in = fread(inBuffer, sizeof(Uint8), SET_TMPBUF_SIZE, pack->file); | 425 zstr.avail_in = fread(inBuffer, sizeof(Uint8), needed, pack->file); |
427 else | 426 if (zstr.avail_in < needed) |
428 zstr.avail_in = fread(inBuffer, sizeof(Uint8), inDataLeft, pack->file); | 427 { |
428 ret = DMERR_FREAD; | |
429 goto out; | |
430 } | |
429 | 431 |
430 remaining -= zstr.avail_in; | 432 remaining -= zstr.avail_in; |
431 zstr.next_in = inBuffer; | 433 zstr.next_in = inBuffer; |
432 | 434 |
433 while (zstr.avail_in > 0 && ret == Z_OK) | 435 if (!decompress) |
434 { | 436 { |
435 zstr.next_out = outBuffer; | 437 if (fwrite(inBuffer, sizeof(Uint8), zstr.avail_in, outFile) != zstr.avail_in) |
438 { | |
439 ret = DMERR_FWRITE; | |
440 goto out; | |
441 } | |
442 } | |
443 else | |
444 while (zstr.avail_in > 0 && zret == Z_OK) | |
445 { | |
446 zstr.next_out = outBuffer; | |
436 zstr.avail_out = SET_TMPBUF_SIZE; | 447 zstr.avail_out = SET_TMPBUF_SIZE; |
437 zstr.total_out = 0; | 448 zstr.total_out = 0; |
438 ret = inflate(&zstr, Z_FULL_FLUSH); | 449 zret = inflate(&zstr, Z_FULL_FLUSH); |
439 if (zstr.total_out > 0) | 450 if (zstr.total_out > 0 && |
440 { | 451 fwrite(outBuffer, sizeof(Uint8), zstr.total_out, outFile) != zstr.total_out) |
441 fwrite(outBuffer, sizeof(Uint8), zstr.total_out, outFile); | 452 { |
442 } | 453 ret = DMERR_FWRITE; |
443 } | 454 goto out; |
444 } | 455 } |
445 | 456 } |
457 } | |
458 | |
459 out: | |
446 // Cleanup | 460 // Cleanup |
447 inflateEnd(&zstr); | 461 if (zinit) |
462 inflateEnd(&zstr); | |
463 | |
448 dmFree(inBuffer); | 464 dmFree(inBuffer); |
449 dmFree(outBuffer); | 465 dmFree(outBuffer); |
450 fclose(outFile); | 466 |
451 | 467 if (outFile != NULL) |
452 return DMERR_OK; | 468 fclose(outFile); |
469 | |
470 return ret; | |
453 } | 471 } |
454 | 472 |
455 | 473 |
456 /* Compare a string to a pattern. Case-SENSITIVE version. | 474 /* Compare a string to a pattern. Case-SENSITIVE version. |
457 * The matching pattern can consist of any normal characters plus | 475 * The matching pattern can consist of any normal characters plus |
629 | 647 |
630 for (i = 0; i < nsrcFilenames; i++) | 648 for (i = 0; i < nsrcFilenames; i++) |
631 if (!dmCheckExcluded(srcFilenames[i])) | 649 if (!dmCheckExcluded(srcFilenames[i])) |
632 { | 650 { |
633 DMPackEntry *node = NULL; | 651 DMPackEntry *node = NULL; |
634 int res = dmPackAddFile(pack, srcFilenames[i], optCompress, optDefResFlags, &node); | 652 int res = dmPackAddFile(pack, srcFilenames[i], |
653 optDefResFlags, optCompress, | |
654 Z_DEFAULT_COMPRESSION, &node); | |
635 | 655 |
636 if (res != DMERR_OK) | 656 if (res != DMERR_OK) |
637 { | 657 { |
638 dmPrint(1, "%-32s [ERROR:%d]\n", | 658 dmPrint(1, "%-32s [ERROR:%d]\n", |
639 srcFilenames[i], res); | 659 srcFilenames[i], res); |
737 // Print one entry | 757 // Print one entry |
738 dmPrint(0, "Extracting: %-32s [siz=%d, cmp=%d, offs=0x%08x, flags=0x%04x]\n", | 758 dmPrint(0, "Extracting: %-32s [siz=%d, cmp=%d, offs=0x%08x, flags=0x%04x]\n", |
739 node->filename, node->size, node->length, | 759 node->filename, node->size, node->length, |
740 node->offset, node->flags); | 760 node->offset, node->flags); |
741 | 761 |
742 dmPackExtractFile(pack, node); | 762 dmPackExtractFile(pack, node, !optCompress); |
743 } | 763 } |
744 } | 764 } |
745 | 765 |
746 dmMsg(1, "c=%d\n", dmPackClose(pack)); | 766 dmMsg(1, "c=%d\n", dmPackClose(pack)); |
747 | 767 |