home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / util / q2source.exe / utils3 / Unpack / Unpack.java < prev    next >
Encoding:
Java Source  |  1997-12-11  |  4.2 KB  |  178 lines

  1.  
  2. /*
  3.  * Unpack -- a completely non-object oriented utility...
  4.  *
  5.  */
  6.  
  7. import java.io.*;
  8.  
  9. class Unpack {
  10.     static final int IDPAKHEADER    = (('K'<<24)+('C'<<16)+('A'<<8)+'P');
  11.  
  12.     static int intSwap(int i) {
  13.         int        a, b, c, d;
  14.  
  15.         a = i & 255;
  16.         b = (i >> 8) & 255;
  17.         c = (i >> 16) & 255;
  18.         d = (i >> 24) & 255;
  19.  
  20.         return (a << 24) + (b << 16) + (c << 8) + d;
  21.     }
  22.  
  23.     static boolean    patternMatch (String pattern, String s) {
  24.         int        index;
  25.         int        remaining;
  26.  
  27.         if (pattern.equals(s)) {
  28.             return true;
  29.         }
  30.  
  31.         // fairly lame single wildcard matching
  32.         index = pattern.indexOf('*');
  33.         if (index == -1) {
  34.             return false;
  35.         }
  36.         if (!pattern.regionMatches(0, s, 0, index)) {
  37.             return false;
  38.         }
  39.  
  40.         index += 1;    // skip the *
  41.         remaining = pattern.length() - index;
  42.         if (s.length() < remaining) {
  43.             return false;
  44.         }
  45.  
  46.         if (!pattern.regionMatches(index, s, s.length()-remaining, remaining)) {
  47.             return false;
  48.         }
  49.  
  50.         return true;
  51.     }
  52.  
  53.     static void usage() {
  54.         System.out.println ("Usage: unpack <packfile> <match> <basedir>");
  55.         System.out.println ("   or: unpack -list <packfile>");
  56.         System.out.println ("<match> may contain a single * wildcard");
  57.         System.exit (1);
  58.     }
  59.  
  60.     public static void main (String[] args) {
  61.         int            ident;
  62.         int            dirofs;
  63.         int            dirlen;
  64.         int            i;
  65.         int            numLumps;
  66.         byte[]        name = new byte[56];
  67.         String        nameString;
  68.         int            filepos;
  69.         int            filelen;
  70.         RandomAccessFile    readLump;
  71.         DataInputStream        directory;
  72.         String        pakName;
  73.         String        pattern;
  74.  
  75.         if (args.length == 2) {
  76.             if (!args[0].equals("-list")) {
  77.                 usage();
  78.             }
  79.             pakName = args[1];
  80.             pattern = null;    
  81.         } else if (args.length == 3) {
  82.             pakName = args[0];
  83.             pattern = args[1];
  84.         } else {
  85.             pakName = null;    
  86.             pattern = null;    
  87.             usage ();
  88.         }
  89.  
  90.         try    {
  91.             // one stream to read the directory
  92.             directory = new DataInputStream(new FileInputStream(pakName));
  93.  
  94.             // another to read lumps
  95.             readLump = new RandomAccessFile(pakName, "r");
  96.  
  97.             // read the header
  98.             ident = intSwap(directory.readInt());
  99.             dirofs = intSwap(directory.readInt());
  100.             dirlen = intSwap(directory.readInt());
  101.  
  102.             if (ident != IDPAKHEADER) {
  103.                 System.out.println ( pakName + " is not a pakfile.");
  104.                 System.exit (1);
  105.             }
  106.  
  107.             // read the directory
  108.             directory.skipBytes (dirofs - 12);
  109.             numLumps = dirlen / 64;
  110.  
  111.             System.out.println (numLumps + " lumps in " + pakName);
  112.  
  113.             for (i = 0 ; i < numLumps ; i++) {
  114.                 directory.readFully(name);
  115.                 filepos = intSwap(directory.readInt());
  116.                 filelen = intSwap(directory.readInt());
  117.  
  118.                 nameString = new String (name, 0);
  119.                 // chop to the first 0 byte
  120.                 nameString = nameString.substring (0, nameString.indexOf(0));
  121.  
  122.                 if (pattern == null) {
  123.                     // listing mode
  124.                     System.out.println (nameString + " : " + filelen + "bytes");
  125.                 } else if (patternMatch (pattern, nameString) ) {
  126.                     File                writeFile;
  127.                     DataOutputStream    writeLump;
  128.                     byte[]                buffer = new byte[filelen];
  129.                     StringBuffer        fixedString;
  130.                     String                finalName;
  131.                     int                    index;
  132.  
  133.                     System.out.println ("Unpaking " + nameString + " " + filelen 
  134.                         + " bytes");
  135.  
  136.                     // load the lump
  137.                     readLump.seek(filepos);
  138.                     readLump.readFully(buffer);
  139.  
  140.                     // quake uses forward slashes, but java requires
  141.                     // they only by the host's seperator, which
  142.                     // varies from win to unix
  143.                     fixedString = new StringBuffer (args[2] + File.separator + nameString);
  144.                     for (index = 0 ; index < fixedString.length() ; index++) {
  145.                         if (fixedString.charAt(index) == '/') {
  146.                             fixedString.setCharAt(index, File.separatorChar);
  147.                         }
  148.                     }
  149.                     finalName = fixedString.toString ();
  150.  
  151.                     index = finalName.lastIndexOf(File.separatorChar);
  152.                     if (index != -1) {
  153.                         String        finalPath;
  154.                         File        writePath;
  155.  
  156.                         finalPath = finalName.substring(0, index);
  157.                         writePath = new File (finalPath);
  158.                         writePath.mkdirs();
  159.                     }
  160.  
  161.                     writeFile = new File (finalName);
  162.                     writeLump = new DataOutputStream ( new FileOutputStream(writeFile) );
  163.                     writeLump.write(buffer);
  164.                     writeLump.close();
  165.                     
  166.                 }
  167.             }
  168.  
  169.             readLump.close();
  170.             directory.close();
  171.  
  172.         } catch (IOException e) {
  173.             System.out.println ( e.toString() );
  174.         }
  175.     }
  176.  
  177. }
  178.