From 8459153c5fdb58f427d13db918c0e15d46a799aa Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 20 Feb 2013 16:52:05 +0100 Subject: [PATCH] version info reader implemented --- .../src/com/pme/exe/Bin.java | 74 ++++++++++ .../com/pme/exe/res/vi/StringFileInfo.java | 32 +++-- .../src/com/pme/exe/res/vi/StringTable.java | 49 +++++++ .../com/pme/exe/res/vi/StringTableEntry.java | 60 +++------ .../com/pme/exe/res/vi/StringTableReader.java | 57 -------- ...ersionInfoReader.java => VersionInfo.java} | 22 +-- .../com/pme/launcher/LauncherGenerator.java | 7 +- .../src/com/pme/util/BitsUtil.java | 11 +- .../pme/util/OffsetTrackingInputStream.java | 127 ++++++++++++++++++ 9 files changed, 307 insertions(+), 132 deletions(-) create mode 100644 tools/launcher-generator/src/com/pme/exe/res/vi/StringTable.java delete mode 100644 tools/launcher-generator/src/com/pme/exe/res/vi/StringTableReader.java rename tools/launcher-generator/src/com/pme/exe/res/vi/{VersionInfoReader.java => VersionInfo.java} (61%) create mode 100644 tools/launcher-generator/src/com/pme/util/OffsetTrackingInputStream.java diff --git a/tools/launcher-generator/src/com/pme/exe/Bin.java b/tools/launcher-generator/src/com/pme/exe/Bin.java index 338793924de7..f73bf529ea07 100644 --- a/tools/launcher-generator/src/com/pme/exe/Bin.java +++ b/tools/launcher-generator/src/com/pme/exe/Bin.java @@ -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; diff --git a/tools/launcher-generator/src/com/pme/exe/res/vi/StringFileInfo.java b/tools/launcher-generator/src/com/pme/exe/res/vi/StringFileInfo.java index 2133db8c9b34..81269b5bb58c 100644 --- a/tools/launcher-generator/src/com/pme/exe/res/vi/StringFileInfo.java +++ b/tools/launcher-generator/src/com/pme/exe/res/vi/StringFileInfo.java @@ -18,26 +18,32 @@ 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 index 000000000000..956cc6f475d7 --- /dev/null +++ b/tools/launcher-generator/src/com/pme/exe/res/vi/StringTable.java @@ -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); + } + } +} diff --git a/tools/launcher-generator/src/com/pme/exe/res/vi/StringTableEntry.java b/tools/launcher-generator/src/com/pme/exe/res/vi/StringTableEntry.java index 03ed67071e8d..8a3193a2ac73 100644 --- a/tools/launcher-generator/src/com/pme/exe/res/vi/StringTableEntry.java +++ b/tools/launcher-generator/src/com/pme/exe/res/vi/StringTableEntry.java @@ -18,58 +18,34 @@ 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(""); 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(); + @Override + public void read(DataInput stream) throws IOException { + super.read(stream); + WChar key = (WChar) getMember("szKey"); + setName(key.getValue()); + } - Txt txt = new Txt("Value", byteArrayOutputStream.toByteArray()); - System.out.println( txt.getText() ); - addMember( txt ); - - offset += sizeInBytes(); - - 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 index 360f19bdfe93..000000000000 --- a/tools/launcher-generator/src/com/pme/exe/res/vi/StringTableReader.java +++ /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 ); - - } -} diff --git a/tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoReader.java b/tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfo.java 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 219c7e562911..0bf14e06c268 100644 --- a/tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfoReader.java +++ b/tools/launcher-generator/src/com/pme/exe/res/vi/VersionInfo.java @@ -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()); } } diff --git a/tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java b/tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java index fe1da5c71068..a5e1bda6b56e 100644 --- a/tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java +++ b/tools/launcher-generator/src/com/pme/launcher/LauncherGenerator.java @@ -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); diff --git a/tools/launcher-generator/src/com/pme/util/BitsUtil.java b/tools/launcher-generator/src/com/pme/util/BitsUtil.java index 73ebf7548252..1303b3e65b24 100644 --- a/tools/launcher-generator/src/com/pme/util/BitsUtil.java +++ b/tools/launcher-generator/src/com/pme/util/BitsUtil.java @@ -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 index 000000000000..10e55918b60d --- /dev/null +++ b/tools/launcher-generator/src/com/pme/util/OffsetTrackingInputStream.java @@ -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(); + } +}