package com.pme.exe;
import com.pme.util.BitsUtil;
+import com.pme.util.OffsetTrackingInputStream;
import java.io.*;
import java.util.ArrayList;
}
}
+ 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;
mySize = new DWord("").setValue(bytes.length);
setValue();
}
+
public Txt(String name, String string) {
super(name);
myBytes = new byte[string.length() * 2];
}
}
+ 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;
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);
+ }
}
}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
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();
}
}
+++ /dev/null
-/*
- * 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 );
-
- }
-}
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());
}
}
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.*;
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);
package com.pme.util;
+import java.io.DataInput;
+import java.io.IOException;
+
/**
* Date: Mar 30, 2006
* Time: 7:10:10 PM
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));
+
+ }
}
--- /dev/null
+/*
+ * 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();
+ }
+}