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