refactor to get rid of all the duplication; writing version info (dunno if it works)
authorDmitry Jemerov <yole@jetbrains.com>
Wed, 27 Mar 2013 17:59:48 +0000 (18:59 +0100)
committerDmitry Jemerov <yole@jetbrains.com>
Wed, 27 Mar 2013 20:18:27 +0000 (21:18 +0100)
tools/launcher-generator/src/com/pme/exe/Bin.java
tools/launcher-generator/src/com/pme/exe/res/vi/StringFileInfo.java
tools/launcher-generator/src/com/pme/exe/res/vi/StringTable.java
tools/launcher-generator/src/com/pme/exe/res/vi/StringTableEntry.java
tools/launcher-generator/src/com/pme/exe/res/vi/Var.java
tools/launcher-generator/src/com/pme/exe/res/vi/VarFileInfo.java
tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfo.java
tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoBin.java [new file with mode: 0644]
tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoFactory.java [new file with mode: 0644]
tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java

index 855e51f2372b1bd4b805fa13f18df13ea9ce7838..ad11eb92c8760ca1dd922259359a8f4646f94e20 100644 (file)
@@ -367,21 +367,26 @@ public abstract class Bin {
 
     @Override
     public long sizeInBytes() {
-      throw new UnsupportedOperationException();
+      return bytesToSkip(getOffset());
     }
 
     @Override
     public void read(DataInput stream) throws IOException {
       if (stream instanceof OffsetTrackingInputStream) {
         long offset = ((OffsetTrackingInputStream) stream).getOffset();
-        int offsetMask = myBytes-1;
-        long offsetBits = offset & offsetMask;
-        if (offsetBits > 0) {
-          stream.skipBytes((int) (myBytes - offsetBits));
+        int skip = bytesToSkip(offset);
+        if (skip > 0) {
+          stream.skipBytes(skip);
         }
       }
     }
 
+    private int bytesToSkip(long offset) {
+      int offsetMask = myBytes-1;
+      long offsetBits = offset & offsetMask;
+      return offsetBits == 0 ? 0 : (int) (myBytes - offsetBits);
+    }
+
     @Override
     public void write(DataOutput stream) throws IOException {
     }
@@ -468,7 +473,7 @@ public abstract class Bin {
 
     @Override
     public long sizeInBytes() {
-      throw new UnsupportedOperationException();
+      return myValue.length() * 2 + 2;
     }
 
     @Override
@@ -484,7 +489,10 @@ public abstract class Bin {
 
     @Override
     public void write(DataOutput stream) throws IOException {
-      throw new UnsupportedOperationException();
+      for (int i = 0; i < myValue.length(); i++) {
+        stream.writeShort(BitsUtil.revertBytesOfShort((short) myValue.charAt(i)));
+      }
+      stream.writeShort(0);
     }
 
     @Override
@@ -580,23 +588,6 @@ public abstract class Bin {
         writer.write(myBuffer.toString());
       }
     }
-
-    public String getAsWChar() {
-      StringBuilder result = new StringBuilder(myBytes.length/2);
-      ByteArrayInputStream bis = new ByteArrayInputStream(myBytes);
-      DataInputStream dis = new DataInputStream(bis);
-      try {
-        for (int i = 0; i < myBytes.length / 2 - 1; i++) {
-          result.append(BitsUtil.readChar(dis));
-        }
-        char terminator = BitsUtil.readChar(dis);
-        assert terminator == '\0';
-      } catch (IOException e) {
-        throw new RuntimeException(e);
-      }
-
-      return result.toString();
-    }
   }
 
   public static class ArrayOfBins<T extends Bin> extends Bin {
index 1b37330f72daf76f5100c4ff5cb15d114625175e..e7ed49184692c69f6648d757644d8560d2f1b0c0 100644 (file)
 
 package com.pme.exe.res.vi;
 
-import com.pme.exe.Bin;
-import com.pme.util.OffsetTrackingInputStream;
-
-import java.io.DataInput;
-import java.io.IOException;
-
-public class StringFileInfo extends Bin.Structure {
+public class StringFileInfo extends VersionInfoBin {
   public StringFileInfo() {
-    super("StringFileInfo");
-    addMember(new Word("wLength"));
-    addMember(new Word("wValueLength"));
-    addMember(new Word("wType"));
-    addMember(new Bytes("szKey", 30));
-    addMember(new Padding(4));
-  }
-
-  @Override
-  public void read(DataInput stream) throws IOException {
-    OffsetTrackingInputStream inputStream = (OffsetTrackingInputStream) stream;
-    long startOffset = inputStream.getOffset();
-    super.read(stream);
-    assert ((Bytes) getMember("szKey")).getAsWChar().equals("StringFileInfo");
-    long length = getValue("wLength");
-    int i = 0;
-    while(inputStream.getOffset() < startOffset + length) {
-      StringTable stringTableReader = new StringTable("StringTable" + (i++));
-      stringTableReader.read(inputStream);
-      addMember(stringTableReader);
-    }
+    super("StringFileInfo", "StringFileInfo", new VersionInfoFactory() {
+      @Override
+      public VersionInfoBin createChild(int index) {
+        return new StringTable("StringTable" + index);
+      }
+    });
   }
 }
index 956cc6f475d7eceb0835da33015ce82915fcf88c..c31657c6f3484427e09b0ac4d4f089d52bc3fb81 100644 (file)
 
 package com.pme.exe.res.vi;
 
-import com.pme.exe.Bin;
-import com.pme.util.OffsetTrackingInputStream;
-
-import java.io.DataInput;
-import java.io.IOException;
-
-public class StringTable extends Bin.Structure {
+public class StringTable extends VersionInfoBin {
 
   public StringTable(String name) {
-    super(name);
-    addMember(new Word("wLength"));
-    addMember(new Word("wValueLength"));
-    addMember(new Word("wType"));
-    addMember(new WChar("szKey"));
-    addMember(new Padding(4));
-  }
-
-  public void read(DataInput stream) throws IOException {
-    OffsetTrackingInputStream inputStream = (OffsetTrackingInputStream) stream;
-    long startOffset = inputStream.getOffset();
-    super.read(stream);
-    long length = getValue("wLength");
-    int i = 0;
-    while(inputStream.getOffset() < startOffset + length) {
-      StringTableEntry stringTableEntry = new StringTableEntry();
-      stringTableEntry.read(inputStream);
-      addMember(stringTableEntry);
-    }
+    super(name, null, new VersionInfoFactory() {
+      @Override
+      public VersionInfoBin createChild(int index) {
+        return new StringTableEntry();
+      }
+    });
   }
 }
index 8a3193a2ac73312f8dca0a4b2cb797442c156065..78914cb41b14d8af0666795ff2816fa6b96a27a5 100644 (file)
 
 package com.pme.exe.res.vi;
 
-import com.pme.exe.Bin;
-import com.pme.util.OffsetTrackingInputStream;
+import java.io.DataInput;
+import java.io.IOException;
 
-import java.io.*;
-import java.util.ArrayList;
-
-public class StringTableEntry extends Bin.Structure {
+public class StringTableEntry extends VersionInfoBin {
   public StringTableEntry() {
     super("<unnamed>");
-    addMember(new Word("wLength"));
-    addMember(new Word("wValueLength"));
-    addMember(new Word("wType"));
-    addMember(new WChar("szKey"));
-    addMember(new Padding(4));
     addMember(new WChar("Value"));
     addMember(new Padding(4));
   }
index 7b1a910bc6f5ada75b3cd14eb6378b4c0641fefa..9c7d8889e4fa7135e7c68d0e20c5396207ee8a56 100644 (file)
@@ -1,32 +1,11 @@
 package com.pme.exe.res.vi;
 
-import com.pme.exe.Bin;
-import com.pme.util.OffsetTrackingInputStream;
-
-import java.io.DataInput;
-import java.io.IOException;
-
 /**
  * @author yole
  */
-public class Var extends Bin.Structure {
+public class Var extends VersionInfoBin {
   public Var(String name) {
-    super(name);
-    addMember(new Word("wLength"));
-    addMember(new Word("wValueLength"));
-    addMember(new Word("wType"));
-    addMember(new Bytes("szKey", 24));
-    addMember(new Padding(4));
+    super(name, "Translation");
     addMember(new DWord("Translation"));
   }
-
-  @Override
-  public void read(DataInput stream) throws IOException {
-    OffsetTrackingInputStream inputStream = (OffsetTrackingInputStream) stream;
-    long startOffset = inputStream.getOffset();
-    assert startOffset % 4 == 0;
-    super.read(stream);
-    String varKey = ((Bytes) getMember("szKey")).getAsWChar();
-    assert varKey.equals("Translation"): "Expected key name Translation, found " + varKey;
-  }
 }
index 97f5ca8d2c8f92783873b2d50044a5079372ef75..f9f8cc584c444df31b462213083b08cb38dba4d3 100644 (file)
@@ -1,36 +1,15 @@
 package com.pme.exe.res.vi;
 
-import com.pme.exe.Bin;
-import com.pme.util.OffsetTrackingInputStream;
-
-import java.io.DataInput;
-import java.io.IOException;
-
 /**
  * @author yole
  */
-public class VarFileInfo extends Bin.Structure {
+public class VarFileInfo extends VersionInfoBin {
   public VarFileInfo() {
-    super("VarFileInfo");
-    addMember(new Word("wLength"));
-    addMember(new Word("wValueLength"));
-    addMember(new Word("wType"));
-    addMember(new Bytes("szKey", 24));
-    addMember(new Padding(4));
-  }
-
-  @Override
-  public void read(DataInput stream) throws IOException {
-    OffsetTrackingInputStream inputStream = (OffsetTrackingInputStream) stream;
-    long startOffset = inputStream.getOffset();
-    super.read(stream);
-    assert ((Bytes) getMember("szKey")).getAsWChar().equals("VarFileInfo");
-    long length = getValue("wLength");
-    int i = 0;
-    while(inputStream.getOffset() < startOffset + length) {
-      Var varReader = new Var("Var" + (i++));
-      varReader.read(inputStream);
-      addMember(varReader);
-    }
+    super("VarFileInfo", "VarFileInfo", new VersionInfoFactory() {
+      @Override
+      public VersionInfoBin createChild(int index) {
+        return new Var("Var" + index);
+      }
+    });
   }
 }
index b57c1f7dbe4f22584c7b9928e936afa1c2a892ae..8924578e853291f6f5b52f76d6f2c1326db6bae0 100644 (file)
 
 package com.pme.exe.res.vi;
 
-import com.pme.exe.Bin;
 import com.pme.util.OffsetTrackingInputStream;
 
 import java.io.DataInput;
 import java.io.IOException;
 
-public class VersionInfo extends Bin.Structure {
+public class VersionInfo extends VersionInfoBin {
   public VersionInfo() {
-    super("VersionInfo");
-    addMember(new Word("wLength"));
-    addMember(new Word("wValueLength"));
-    addMember(new Word("wType"));
-    addMember(new Bytes("szKey", 32));
-    addMember(new Padding(4));
+    super("VersionInfo", "VS_VERSION_INFO");
     addMember(new FixedFileInfo());
     addMember(new Padding(4));
     addMember(new StringFileInfo());
@@ -44,8 +38,6 @@ public class VersionInfo extends Bin.Structure {
       startOffset = ((OffsetTrackingInputStream) stream).getOffset();
     }
     super.read(stream);
-    String signature = ((Bytes) getMember("szKey")).getAsWChar();
-    assert signature.equals("VS_VERSION_INFO"): "Expected signature VS_VERSION_INFO, found '" + signature + "'";
     if (stream instanceof OffsetTrackingInputStream) {
       long offset = ((OffsetTrackingInputStream) stream).getOffset();
       long length = getValue("wLength");
diff --git a/tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoBin.java b/tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoBin.java
new file mode 100644 (file)
index 0000000..6c2d491
--- /dev/null
@@ -0,0 +1,57 @@
+package com.pme.exe.res.vi;
+
+import com.pme.exe.Bin;
+import com.pme.util.OffsetTrackingInputStream;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+/**
+ * @author yole
+ */
+public class VersionInfoBin extends Bin.Structure {
+  private String myExpectedName;
+  private VersionInfoFactory myChildFactory;
+
+  public VersionInfoBin(String name) {
+    super(name);
+    Word length = new Word("wLength");
+    addMember(length);
+    addSizeHolder(length);
+    addMember(new Word("wValueLength"));
+    addMember(new Word("wType"));
+    addMember(new WChar("szKey"));
+    addMember(new Padding(4));
+  }
+
+  public VersionInfoBin(String versionInfo, String expectedName) {
+    this(versionInfo);
+    myExpectedName = expectedName;
+  }
+
+  public VersionInfoBin(String versionInfo, String expectedName, VersionInfoFactory childFactory) {
+    this(versionInfo, expectedName);
+    myChildFactory = childFactory;
+  }
+
+  @Override
+  public void read(DataInput stream) throws IOException {
+    OffsetTrackingInputStream inputStream = (OffsetTrackingInputStream) stream;
+    long startOffset = inputStream.getOffset();
+    assert startOffset % 4 == 0;
+    super.read(stream);
+    if (myExpectedName != null) {
+      String signature = ((WChar) getMember("szKey")).getValue();
+      assert signature.equals(myExpectedName): "Expected signature " + myExpectedName + ", found '" + signature + "'";
+    }
+    if (myChildFactory != null) {
+      long length = getValue("wLength");
+      int i = 0;
+      while(inputStream.getOffset() < startOffset + length) {
+        VersionInfoBin child = myChildFactory.createChild(i++);
+        child.read(inputStream);
+        addMember(child);
+      }
+    }
+  }
+}
diff --git a/tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoFactory.java b/tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoFactory.java
new file mode 100644 (file)
index 0000000..6253b27
--- /dev/null
@@ -0,0 +1,8 @@
+package com.pme.exe.res.vi;
+
+/**
+ * @author yole
+ */
+public interface VersionInfoFactory {
+  VersionInfoBin createChild(int index);
+}
index 0b76f89f927f4df8e5662da1f8f7ae6c74c56525..185abd6b1e02bb2a57655fba9a58da23c23531ba 100644 (file)
@@ -79,6 +79,10 @@ public class LauncherGenerator {
     RandomAccessFile exeStream = new RandomAccessFile(myExePath, "rw");
     myReader.write(exeStream);
     exeStream.close();
+
+    RandomAccessFile versionInfoStream = new RandomAccessFile(myExePath + ".version", "rw");
+    myVersionInfo.resetOffsets(0);
+    myVersionInfo.write(versionInfoStream);
   }
 
   public void setResourceString(int id, String value) {