version info reader implemented
authorDmitry Jemerov <yole@jetbrains.com>
Wed, 20 Feb 2013 15:52:05 +0000 (16:52 +0100)
committerDmitry Jemerov <yole@jetbrains.com>
Wed, 20 Feb 2013 19:14:10 +0000 (20:14 +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 [new file with mode: 0644]
tools/launcher-generator/src/com/pme/exe/res/vi/StringTableEntry.java
tools/launcher-generator/src/com/pme/exe/res/vi/StringTableReader.java [deleted file]
tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfo.java [moved from tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoReader.java with 61% similarity]
tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java
tools/launcher-generator/src/com/pme/util/BitsUtil.java
tools/launcher-generator/src/com/pme/util/OffsetTrackingInputStream.java [new file with mode: 0644]

index 338793924de744ab30f89fc724c8fbdfe8681f53..f73bf529ea076cbc0a2f018fbecb33baa9fb5741 100644 (file)
@@ -18,6 +18,7 @@
 package com.pme.exe;
 
 import com.pme.util.BitsUtil;
+import com.pme.util.OffsetTrackingInputStream;
 
 import java.io.*;
 import java.util.ArrayList;
@@ -356,6 +357,40 @@ public abstract class Bin {
     }
   }
 
+  public static class Padding extends Bin {
+    private int myBytes;
+
+    public Padding(int bytes) {
+      super("Padding");
+      myBytes = bytes;
+    }
+
+    @Override
+    public long sizeInBytes() {
+      throw new UnsupportedOperationException();
+    }
+
+    @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));
+        }
+      }
+    }
+
+    @Override
+    public void write(DataOutput stream) throws IOException {
+    }
+
+    @Override
+    public void report(OutputStreamWriter writer) throws IOException {
+    }
+  }
+
   public static class Txt extends Bin {
     private StringBuffer myBuffer = new StringBuffer();
     private Bin.Value mySize;
@@ -367,6 +402,7 @@ public abstract class Bin {
       mySize = new DWord("").setValue(bytes.length);
       setValue();
     }
+
     public Txt(String name, String string) {
       super(name);
       myBytes = new byte[string.length() * 2];
@@ -423,6 +459,44 @@ public abstract class Bin {
     }
   }
 
+  public static class WChar extends Bin {
+    private String myValue;
+
+    public WChar(String name) {
+      super(name);
+    }
+
+    @Override
+    public long sizeInBytes() {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void read(DataInput stream) throws IOException {
+      StringBuilder valueBuilder = new StringBuilder();
+      while(true) {
+        char c = BitsUtil.readChar(stream);
+        if (c == 0) break;
+        valueBuilder.append(c);
+      }
+      myValue = valueBuilder.toString();
+    }
+
+    @Override
+    public void write(DataOutput stream) throws IOException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void report(OutputStreamWriter writer) throws IOException {
+      _report(writer, myValue);
+    }
+
+    public String getValue() {
+      return myValue;
+    }
+  }
+
   public static class Bytes extends Bin {
     private byte[] myBytes;
     private Value myStartOffset;
index 2133db8c9b34836b8df3290bce83084e0fe4ce70..81269b5bb58cb82a9092c2d8fc2bf363a3a81dc1 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;
 
-/**
- * Date: May 10, 2006
- * Time: 8:01:15 PM
- */
 public class StringFileInfo extends Bin.Structure {
   public StringFileInfo() {
     super("StringFileInfo");
-    addMember( new Word( "wLength" ) );
-    addMember( new Word( "wValueLength" ) );
-    addMember( new Word( "wType" ) );
-    addMember( new Bytes( "Bytes", 30 ) );
+    addMember(new Word("wLength"));
+    addMember(new Word("wValueLength"));
+    addMember(new Word("wType"));
+    addMember(new WChar("szKey"));
+    addMember(new Padding(4));
   }
-  public void readWithPadding( DataInput stream, long offset ) throws IOException {
-    read( stream );
-    StringTableReader stringTableReader = new StringTableReader();
-    stringTableReader.readWithPadding( stream, offset + sizeInBytes() );
-    addMember( stringTableReader );
+
+  @Override
+  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) {
+      StringTable stringTableReader = new StringTable("StringTable" + (i++));
+      stringTableReader.read(inputStream);
+      addMember(stringTableReader);
+    }
   }
 }
diff --git a/tools/launcher-generator/src/com/pme/exe/res/vi/StringTable.java b/tools/launcher-generator/src/com/pme/exe/res/vi/StringTable.java
new file mode 100644 (file)
index 0000000..956cc6f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2006 ProductiveMe Inc.
+ * Copyright 2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 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);
+    }
+  }
+}
index 03ed67071e8dd60a794f98b678bd5ec8cb9e47a3..8a3193a2ac73312f8dca0a4b2cb797442c156065 100644 (file)
 package com.pme.exe.res.vi;
 
 import com.pme.exe.Bin;
+import com.pme.util.OffsetTrackingInputStream;
 
 import java.io.*;
 import java.util.ArrayList;
 
-/**
- * Date: May 10, 2006
- * Time: 8:26:03 PM
- */
 public class StringTableEntry extends Bin.Structure {
-  public StringTableEntry(String key) {
-    super(key);
+  public StringTableEntry() {
+    super("<unnamed>");
     addMember(new Word("wLength"));
     addMember(new Word("wValueLength"));
     addMember(new Word("wType"));
-    addMember(new Bytes("key", key.length() * 2));
+    addMember(new WChar("szKey"));
+    addMember(new Padding(4));
+    addMember(new WChar("Value"));
+    addMember(new Padding(4));
   }
 
-  public void readWithPadding(DataInput stream, long offset) throws IOException {
-    read(stream);
-    long off = offset + sizeInBytes();
-    Bytes padding = new Bytes("Padding", off % 8);
-    padding.read(stream);
-    addMember(padding);
-    ArrayList list = new ArrayList();
-    for(int i = 0;;++i){
-      Word word = new Word( "" + i );
-      word.read( stream );
-      list.add( word );
-      if ( word.getValue() == 0 ) break;
-    }
-    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(list.size() * 2);
-    DataOutputStream bytesStream = new DataOutputStream( byteArrayOutputStream );
-    for (int i = 0; i < list.size(); ++i) {
-      Word word = (Word)list.get(i);
-      word.write( bytesStream );
-    }
-    bytesStream.close();
-
-    Txt txt = new Txt("Value", byteArrayOutputStream.toByteArray());
-    System.out.println( txt.getText() );
-    addMember( txt );
-
-    offset += sizeInBytes();
+  @Override
+  public void read(DataInput stream) throws IOException {
+    super.read(stream);
+    WChar key = (WChar) getMember("szKey");
+    setName(key.getValue());
+  }
 
-    System.out.println( "" + offset % 8 );
-    System.out.println( "" + offset % 4 );
-    System.out.println( "" + offset % 16 );
-    long r = offset % 8;
-    if ( r > 0 ){
-      Bytes padding2 = new Bytes( "Padding2", r );
-      padding2.read( stream );
-      addMember( padding2 );
-    }
+  @Override
+  public String toString() {
+    WChar key = (WChar) getMember("szKey");
+    WChar value = (WChar) getMember("Value");
+    return key.getValue() + " = " + value.getValue();
   }
 }
diff --git a/tools/launcher-generator/src/com/pme/exe/res/vi/StringTableReader.java b/tools/launcher-generator/src/com/pme/exe/res/vi/StringTableReader.java
deleted file mode 100644 (file)
index 360f19b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2006 ProductiveMe Inc.
- * Copyright 2013 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.pme.exe.res.vi;
-
-import com.pme.exe.Bin;
-
-import java.io.DataInput;
-import java.io.IOException;
-
-/**
- * Date: May 10, 2006
- * Time: 8:09:42 PM
- */
-public class StringTableReader extends Bin.Structure{
-
-  public StringTableReader() {
-    super("StringTable");
-    addMember( new Word( "wLength" ) );
-    addMember( new Word( "wValueLength" ) );
-    addMember( new Word( "wType" ) );
-    addMember( new Bytes( "Bytes", 18 ) );
-  }
-  public void readWithPadding( DataInput stream, long offset ) throws IOException {
-    read(stream);
-    StringTableEntry stringTableEntry = new StringTableEntry("CompanyName");
-    stringTableEntry.readWithPadding( stream, offset + sizeInBytes() );
-    addMember( stringTableEntry );
-
-    StringTableEntry desc = new StringTableEntry("FileDescription");
-    desc.readWithPadding( stream, offset + sizeInBytes() + stringTableEntry.sizeInBytes() );
-    addMember( desc );
-
-    StringTableEntry fileVersion = new StringTableEntry("FileVersion");
-    fileVersion.readWithPadding( stream, offset + sizeInBytes() + stringTableEntry.sizeInBytes() + desc.sizeInBytes() );
-    addMember( fileVersion );
-
-    StringTableEntry internalName = new StringTableEntry("InternalName");
-    internalName.readWithPadding( stream, offset + sizeInBytes() + stringTableEntry.sizeInBytes() + desc.sizeInBytes() + fileVersion.sizeInBytes() );
-    addMember( internalName );
-
-  }
-}
similarity index 61%
rename from tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoReader.java
rename to tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfo.java
index 219c7e56291167d42fa9e416ea10edfa6ef5264e..0bf14e06c268c2888e465311f02fc3c14feeb27e 100644 (file)
@@ -22,22 +22,12 @@ import com.pme.exe.Bin;
 import java.io.DataInput;
 import java.io.IOException;
 
-/**
- * Date: May 10, 2006
- * Time: 1:33:34 PM
- */
-public class VersionInfoReader extends Bin.Structure {
-  public VersionInfoReader() {
+public class VersionInfo extends Bin.Structure {
+  public VersionInfo() {
     super("VersionInfo");
-    addMember( new Word("wLength") );
-    addMember( new Bytes( "Bytes", 38 ) );
-    addMember( new FixedFileInfo() );
-  }
-
-  public void read(DataInput stream) throws IOException {
-    super.read(stream);
-    StringFileInfo stringFileInfo = new StringFileInfo();
-    stringFileInfo.readWithPadding( stream, sizeInBytes() );
-    addMember( stringFileInfo );
+    addMember(new Word("wLength"));
+    addMember(new Bytes("Bytes", 38));
+    addMember(new FixedFileInfo());
+    addMember(new StringFileInfo());
   }
 }
index fe1da5c7106878abc507807ae30561b34d8e04aa..a5e1bda6b56eb685ff1d51330720068ee29a4a67 100644 (file)
@@ -26,7 +26,8 @@ import com.pme.exe.res.RawResource;
 import com.pme.exe.res.StringTable;
 import com.pme.exe.res.bmp.PictureResourceInjector;
 import com.pme.exe.res.icon.IconResourceInjector;
-import com.pme.exe.res.vi.VersionInfoReader;
+import com.pme.exe.res.vi.VersionInfo;
+import com.pme.util.OffsetTrackingInputStream;
 
 import java.io.*;
 
@@ -148,8 +149,8 @@ public class LauncherGenerator {
     Bin.Bytes viBytes = viDir.getRawResource( 0 ).getBytes();
     ByteArrayInputStream bytesStream = new ByteArrayInputStream(viBytes.getBytes());
 
-    VersionInfoReader viReader = new VersionInfoReader();
-    viReader.read(new DataInputStream(bytesStream));
+    VersionInfo viReader = new VersionInfo();
+    viReader.read(new OffsetTrackingInputStream(new DataInputStream(bytesStream)));
 
     reader.resetOffsets(0);
 
index 73ebf7548252c14ad631f151dca15f816430dacc..1303b3e65b24e897a3913814cd8abed6fffc768b 100644 (file)
@@ -17,6 +17,9 @@
 
 package com.pme.util;
 
+import java.io.DataInput;
+import java.io.IOException;
+
 /**
  * Date: Mar 30, 2006
  * Time: 7:10:10 PM
@@ -59,5 +62,11 @@ public class BitsUtil {
   public static String byteToHexString( int value ){
     return toHexString( value, 2 );
   }
-  
+
+  public static char readChar(DataInput stream) throws IOException {
+    int b1 = stream.readByte();
+    int b2 = stream.readByte();
+    return (char) (b1 + (b2 << 8));
+
+  }
 }
diff --git a/tools/launcher-generator/src/com/pme/util/OffsetTrackingInputStream.java b/tools/launcher-generator/src/com/pme/util/OffsetTrackingInputStream.java
new file mode 100644 (file)
index 0000000..10e5591
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2006 ProductiveMe Inc.
+ * Copyright 2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pme.util;
+
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * @author yole
+ */
+public class OffsetTrackingInputStream implements DataInput {
+  private final DataInputStream myBaseStream;
+  private long myOffset = 0;
+
+  public OffsetTrackingInputStream(DataInputStream baseStream) {
+    myBaseStream = baseStream;
+  }
+
+  public long getOffset() {
+    return myOffset;
+  }
+
+  @Override
+  public void readFully(byte[] b) throws IOException {
+    myBaseStream.readFully(b);
+    myOffset += b.length;
+  }
+
+  @Override
+  public void readFully(byte[] b, int off, int len) throws IOException {
+    myBaseStream.readFully(b, off, len);
+    myOffset += len;
+  }
+
+  @Override
+  public int skipBytes(int n) throws IOException {
+    int skipped = myBaseStream.skipBytes(n);
+    myOffset += skipped;
+    return skipped;
+  }
+
+  @Override
+  public boolean readBoolean() throws IOException {
+    myOffset++;
+    return myBaseStream.readBoolean();
+  }
+
+  @Override
+  public byte readByte() throws IOException {
+    myOffset++;
+    return myBaseStream.readByte();
+  }
+
+  @Override
+  public int readUnsignedByte() throws IOException {
+    myOffset++;
+    return myBaseStream.readUnsignedByte();
+  }
+
+  @Override
+  public short readShort() throws IOException {
+    myOffset += 2;
+    return myBaseStream.readShort();
+  }
+
+  @Override
+  public int readUnsignedShort() throws IOException {
+    myOffset += 2;
+    return myBaseStream.readUnsignedShort();
+  }
+
+  @Override
+  public char readChar() throws IOException {
+    myOffset += 2;
+    return myBaseStream.readChar();
+  }
+
+  @Override
+  public int readInt() throws IOException {
+    myOffset += 4;
+    return myBaseStream.readInt();
+  }
+
+  @Override
+  public long readLong() throws IOException {
+    myOffset += 8;
+    return myBaseStream.readLong();
+  }
+
+  @Override
+  public float readFloat() throws IOException {
+    myOffset += 4;
+    return myBaseStream.readFloat();
+  }
+
+  @Override
+  public double readDouble() throws IOException {
+    myOffset += 8;
+    return myBaseStream.readDouble();
+  }
+
+  @Override
+  public String readLine() throws IOException {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public String readUTF() throws IOException {
+    throw new UnsupportedOperationException();
+  }
+}