Joining files…

Monday, February 28th, 2005 - Español English

Today comes more stuff from my work. This time I had to join some files and build some info about this joining to prepare resources for a cellphone doja game. So I wrote a simple little perl script to be used as part of the same project’s build process.. It packs (without compressing) graphics and sound files into an archive and writes code (#defines with offsets and file sizes) to enable the application to use them.

In case (quite unlikely, I must admit) that you are interested by this script, here it is.

What the code does is read files from a directory, and output the following:

  • A .txt file with the names of the files in the archive.
  • A .h file ready to be included as code to be preprocessed which defines constants relative to each file in the archive: index, byte offset, and size.
  • A .jfl file with all the files concatenated.
  1. #!/usr/bin/perl
  2. #
  3. # 'joinfile.pl' [ MBD 16:46 28/02/2005 ]
  4. #
  5. # Joins files and builds some info.
  6. #
  7. # Usage:
  8. # joinfile [dir] [basename] [addheader]
  9. #
  10. # [addheader]: false|true. Optional, defaults to false, appends a header to
  11. # the archive: first byte: number of files, followed by file sizes in two
  12. # byte words, big endian.
  13.  
  14. use strict;
  15. use warnings;
  16. use File::Basename;
  17.  
  18. #
  19. if (@ARGV < 2) {
  20. print ("\nUsage:\n\tjoinfile <dir> <basename> [addheader]\n\n");
  21. exit (1);
  22. }
  23.  
  24. # parameters
  25. my ($dir, $base, $hdr) = @ARGV;
  26. my @list = glob("$dir/*");
  27.  
  28. # define args if not provided
  29. $hdr = (defined($hdr) && $hdr eq "true") ? 1 : 0;
  30.  
  31. # Create output files;
  32. my ($of, $oh, $ot);
  33.  
  34. open ($of, ">$base.jfl") or
  35. die ("Unable to create $base.jfl for writing.");
  36. binmode($of);
  37.  
  38. open ($oh, ">$base.hed") or
  39. die ("Unable to create $base.hed for writing.");
  40.  
  41. open ($ot, ">$base.txt") or
  42. die ("Unable to create $base.txt for writing.");
  43.  
  44.  
  45. # Write .hed's first lines:
  46. my $upbase = uc(basename($base));
  47. $upbase =~ tr/\./_/;
  48. print $oh "#ifndef __${upbase}_HED__\n";
  49. print $oh "#define __${upbase}_HED__\n\n";
  50.  
  51. # Write archive's header if requested
  52. # FIXME! quick hack, check for errors, stat files only once...
  53. if ($hdr) {
  54. print $of pack('C', scalar(@list));
  55.  
  56. foreach my $file (@list) {
  57. my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
  58. $atime, $mtime, $ctime, $blksize, $blocks) = stat ($file);
  59.  
  60. print $of pack('S', $size);
  61. }
  62. }
  63.  
  64. # Process each input file:
  65. my $idx = 0;
  66. my $ofs = 0;
  67. foreach my $file (@list) {
  68. # Open file and get info
  69. my $if;
  70. open ($if, "<$file") or
  71. die ("Unable to open $file for reading");
  72. binmode($if);
  73. my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
  74. $atime, $mtime, $ctime, $blksize, $blocks) = stat ($if);
  75.  
  76. # Read file contents and append to result
  77. my $contents;
  78. my $cnt = read($if, $contents, $size);
  79. print $of $contents;
  80. close ($if);
  81.  
  82. # Add info to .hed
  83. my $upfile = uc(basename($file));
  84. $upfile =~ s|^\./||; # remove leading "./"
  85. $upfile =~ tr/\./_/; # replace "." with "_"
  86.  
  87. print $oh "\t#define ${upbase}_${upfile}_IDX $idx\n";
  88. print $oh "\t#define ${upbase}_${upfile}_OFS $ofs\n";
  89. print $oh "\t#define ${upbase}_${upfile}_BYTE $size\n";
  90. print $oh "\n";
  91.  
  92. # Add info to .txt
  93. print $ot basename($file)."\n";
  94.  
  95. $idx++;
  96. $ofs += $size;
  97. }
  98.  
  99. # Finish .hed file
  100. print $oh "\t#define ${upbase}_JFL_SIZE $ofs\n";
  101. print $oh "\t#define ${upbase}_JFL_MAX $idx\n\n";
  102. print $oh "#endif\n";
  103.  
  104. # Close file handles
  105. close ($oh);
  106. close ($of);
  107. close ($ot);
  108.  
  109.  

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>