mirror of
https://github.com/revanced/Apktool.git
synced 2025-01-25 19:27:35 +01:00
Replace little endian data input stream implementation
* Drop LEDataInputStream (which had a restrictive license) with LittleEndianDataInputStream, which is public domain. A minor change has been made to the new class, removing the interitance of InputStream. This makes it's behaviour indentical to the previous implementation, and unit tests pass. Fixes #1166 Source: http://www.peterfranza.com/2008/09/26/little-endian-input-stream/
This commit is contained in:
parent
a7535f36d9
commit
26b60364fb
@ -23,7 +23,7 @@ import brut.androlib.res.data.value.*;
|
||||
import brut.util.Duo;
|
||||
import brut.androlib.res.data.ResTable;
|
||||
import brut.util.ExtDataInput;
|
||||
import com.mindprod.ledatastream.LEDataInputStream;
|
||||
import com.peterfranza.LittleEndianDataInputStream;
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
@ -61,7 +61,7 @@ public class ARSCDecoder {
|
||||
mCountIn = null;
|
||||
mFlagsOffsets = null;
|
||||
}
|
||||
mIn = new ExtDataInput(new LEDataInputStream(arscStream));
|
||||
mIn = new ExtDataInput(new LittleEndianDataInputStream(arscStream));
|
||||
mResTable = resTable;
|
||||
mKeepBroken = keepBroken;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import android.util.TypedValue;
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.xml.ResXmlEncoders;
|
||||
import brut.util.ExtDataInput;
|
||||
import com.mindprod.ledatastream.LEDataInputStream;
|
||||
import com.peterfranza.LittleEndianDataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
@ -69,7 +69,7 @@ public class AXmlResourceParser implements XmlResourceParser {
|
||||
public void open(InputStream stream) {
|
||||
close();
|
||||
if (stream != null) {
|
||||
m_reader = new ExtDataInput(new LEDataInputStream(stream));
|
||||
m_reader = new ExtDataInput(new LittleEndianDataInputStream(stream));
|
||||
}
|
||||
}
|
||||
|
||||
@ -994,4 +994,4 @@ public class AXmlResourceParser implements XmlResourceParser {
|
||||
CHUNK_XML_END_NAMESPACE = 0x00100101,
|
||||
CHUNK_XML_START_TAG = 0x00100102, CHUNK_XML_END_TAG = 0x00100103,
|
||||
CHUNK_XML_TEXT = 0x00100104, CHUNK_XML_LAST = 0x00100104;
|
||||
}
|
||||
}
|
||||
|
@ -1,330 +0,0 @@
|
||||
/*
|
||||
* @(#)LEDataInputStream.java
|
||||
*
|
||||
* Summary: Little-Endian version of DataInputStream.
|
||||
*
|
||||
* Copyright: (c) 1998-2010 Roedy Green, Canadian Mind Products, http://mindprod.com
|
||||
*
|
||||
* Licence: This software may be copied and used freely for any purpose but military.
|
||||
* http://mindprod.com/contact/nonmil.html
|
||||
*
|
||||
* Requires: JDK 1.1+
|
||||
*
|
||||
* Created with: IntelliJ IDEA IDE.
|
||||
*
|
||||
* Version History:
|
||||
* 1.8 2007-05-24
|
||||
*/
|
||||
package com.mindprod.ledatastream;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Little-Endian version of DataInputStream.
|
||||
* <p/>
|
||||
* Very similar to DataInputStream except it reads little-endian instead of
|
||||
* big-endian binary data. We can't extend DataInputStream directly since it has
|
||||
* only final methods, though DataInputStream itself is not final. This forces
|
||||
* us implement LEDataInputStream with a DataInputStream object, and use wrapper
|
||||
* methods.
|
||||
*
|
||||
* @author Roedy Green, Canadian Mind Products
|
||||
* @version 1.8 2007-05-24
|
||||
* @since 1998
|
||||
*/
|
||||
public final class LEDataInputStream implements DataInput {
|
||||
// ------------------------------ CONSTANTS ------------------------------
|
||||
|
||||
/**
|
||||
* undisplayed copyright notice.
|
||||
*
|
||||
* @noinspection UnusedDeclaration
|
||||
*/
|
||||
private static final String EMBEDDED_COPYRIGHT = "copyright (c) 1999-2010 Roedy Green, Canadian Mind Products, http://mindprod.com";
|
||||
|
||||
// ------------------------------ FIELDS ------------------------------
|
||||
|
||||
/**
|
||||
* to get at the big-Endian methods of a basic DataInputStream
|
||||
*
|
||||
* @noinspection WeakerAccess
|
||||
*/
|
||||
protected final DataInputStream dis;
|
||||
|
||||
/**
|
||||
* to get at the a basic readBytes method.
|
||||
*
|
||||
* @noinspection WeakerAccess
|
||||
*/
|
||||
protected final InputStream is;
|
||||
|
||||
/**
|
||||
* work array for buffering input.
|
||||
*
|
||||
* @noinspection WeakerAccess
|
||||
*/
|
||||
protected final byte[] work;
|
||||
|
||||
// -------------------------- PUBLIC STATIC METHODS
|
||||
// --------------------------
|
||||
|
||||
/**
|
||||
* Note. This is a STATIC method!
|
||||
*
|
||||
* @param in
|
||||
* stream to read UTF chars from (endian irrelevant)
|
||||
*
|
||||
* @return string from stream
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
*/
|
||||
public static String readUTF(DataInput in) throws IOException {
|
||||
return DataInputStream.readUTF(in);
|
||||
}
|
||||
|
||||
// -------------------------- PUBLIC INSTANCE METHODS
|
||||
// --------------------------
|
||||
|
||||
/**
|
||||
* constructor.
|
||||
*
|
||||
* @param in
|
||||
* binary inputstream of little-endian data.
|
||||
*/
|
||||
public LEDataInputStream(InputStream in) {
|
||||
this.is = in;
|
||||
this.dis = new DataInputStream(in);
|
||||
work = new byte[8];
|
||||
}
|
||||
|
||||
/**
|
||||
* close.
|
||||
*
|
||||
* @throws IOException
|
||||
* if close fails.
|
||||
*/
|
||||
public final void close() throws IOException {
|
||||
dis.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bytes. Watch out, read may return fewer bytes than requested.
|
||||
*
|
||||
* @param ba
|
||||
* where the bytes go.
|
||||
* @param off
|
||||
* offset in buffer, not offset in file.
|
||||
* @param len
|
||||
* count of bytes to read.
|
||||
*
|
||||
* @return how many bytes read.
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
*/
|
||||
public final int read(byte ba[], int off, int len) throws IOException {
|
||||
// For efficiency, we avoid one layer of wrapper
|
||||
return is.read(ba, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* read only a one-byte boolean.
|
||||
*
|
||||
* @return true or false.
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
* @see java.io.DataInput#readBoolean()
|
||||
*/
|
||||
@Override
|
||||
public final boolean readBoolean() throws IOException {
|
||||
return dis.readBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* read byte.
|
||||
*
|
||||
* @return the byte read.
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
* @see java.io.DataInput#readByte()
|
||||
*/
|
||||
@Override
|
||||
public final byte readByte() throws IOException {
|
||||
return dis.readByte();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read on char. like DataInputStream.readChar except little endian.
|
||||
*
|
||||
* @return little endian 16-bit unicode char from the stream.
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
*/
|
||||
@Override
|
||||
public final char readChar() throws IOException {
|
||||
dis.readFully(work, 0, 2);
|
||||
return (char) ((work[1] & 0xff) << 8 | (work[0] & 0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a double. like DataInputStream.readDouble except little endian.
|
||||
*
|
||||
* @return little endian IEEE double from the datastream.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public final double readDouble() throws IOException {
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one float. Like DataInputStream.readFloat except little endian.
|
||||
*
|
||||
* @return little endian IEEE float from the datastream.
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
*/
|
||||
@Override
|
||||
public final float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bytes until the array is filled.
|
||||
*
|
||||
* @see java.io.DataInput#readFully(byte[])
|
||||
*/
|
||||
@Override
|
||||
public final void readFully(byte ba[]) throws IOException {
|
||||
dis.readFully(ba, 0, ba.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bytes until the count is satisfied.
|
||||
*
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
* @see java.io.DataInput#readFully(byte[],int,int)
|
||||
*/
|
||||
@Override
|
||||
public final void readFully(byte ba[], int off, int len) throws IOException {
|
||||
dis.readFully(ba, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an int, 32-bits. Like DataInputStream.readInt except little endian.
|
||||
*
|
||||
* @return little-endian binary int from the datastream
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
*/
|
||||
@Override
|
||||
public final int readInt() throws IOException {
|
||||
dis.readFully(work, 0, 4);
|
||||
return (work[3]) << 24 | (work[2] & 0xff) << 16 | (work[1] & 0xff) << 8
|
||||
| (work[0] & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a line.
|
||||
*
|
||||
* @return a rough approximation of the 8-bit stream as a 16-bit unicode
|
||||
* string
|
||||
* @throws IOException
|
||||
* @noinspection deprecation
|
||||
* @deprecated This method does not properly convert bytes to characters.
|
||||
* Use a Reader instead with a little-endian encoding.
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public final String readLine() throws IOException {
|
||||
return dis.readLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* read a long, 64-bits. Like DataInputStream.readLong except little endian.
|
||||
*
|
||||
* @return little-endian binary long from the datastream.
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public final long readLong() throws IOException {
|
||||
dis.readFully(work, 0, 8);
|
||||
return (long) (work[7]) << 56 |
|
||||
/* long cast needed or shift done modulo 32 */
|
||||
(long) (work[6] & 0xff) << 48 | (long) (work[5] & 0xff) << 40
|
||||
| (long) (work[4] & 0xff) << 32 | (long) (work[3] & 0xff) << 24
|
||||
| (long) (work[2] & 0xff) << 16 | (long) (work[1] & 0xff) << 8
|
||||
| work[0] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read short, 16-bits. Like DataInputStream.readShort except little endian.
|
||||
*
|
||||
* @return little endian binary short from stream.
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
*/
|
||||
@Override
|
||||
public final short readShort() throws IOException {
|
||||
dis.readFully(work, 0, 2);
|
||||
return (short) ((work[1] & 0xff) << 8 | (work[0] & 0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read UTF counted string.
|
||||
*
|
||||
* @return String read.
|
||||
*/
|
||||
@Override
|
||||
public final String readUTF() throws IOException {
|
||||
return dis.readUTF();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an unsigned byte. Note: returns an int, even though says Byte
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
* @see java.io.DataInput#readUnsignedByte()
|
||||
*/
|
||||
@Override
|
||||
public final int readUnsignedByte() throws IOException {
|
||||
return dis.readUnsignedByte();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an unsigned short, 16 bits. Like DataInputStream.readUnsignedShort
|
||||
* except little endian. Note, returns int even though it reads a short.
|
||||
*
|
||||
* @return little-endian int from the stream.
|
||||
* @throws IOException
|
||||
* if read fails.
|
||||
*/
|
||||
@Override
|
||||
public final int readUnsignedShort() throws IOException {
|
||||
dis.readFully(work, 0, 2);
|
||||
return ((work[1] & 0xff) << 8 | (work[0] & 0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip over bytes in the stream. See the general contract of the
|
||||
* <code>skipBytes</code> method of <code>DataInput</code>.
|
||||
* <p/>
|
||||
* Bytes for this operation are read from the contained input stream.
|
||||
*
|
||||
* @param n
|
||||
* the number of bytes to be skipped.
|
||||
*
|
||||
* @return the actual number of bytes skipped.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
@Override
|
||||
public final int skipBytes(int n) throws IOException {
|
||||
return dis.skipBytes(n);
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.peterfranza;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class LittleEndianDataInputStream implements DataInput {
|
||||
|
||||
public LittleEndianDataInputStream(InputStream in) {
|
||||
this.in = in;
|
||||
this.d = new DataInputStream(in);
|
||||
w = new byte[8];
|
||||
}
|
||||
|
||||
public int available() throws IOException {
|
||||
return d.available();
|
||||
}
|
||||
|
||||
|
||||
public final short readShort() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 2);
|
||||
return (short)(
|
||||
(w[1]&0xff) << 8 |
|
||||
(w[0]&0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* Note, returns int even though it reads a short.
|
||||
*/
|
||||
public final int readUnsignedShort() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 2);
|
||||
return (
|
||||
(w[1]&0xff) << 8 |
|
||||
(w[0]&0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* like DataInputStream.readChar except little endian.
|
||||
*/
|
||||
public final char readChar() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 2);
|
||||
return (char) (
|
||||
(w[1]&0xff) << 8 |
|
||||
(w[0]&0xff));
|
||||
}
|
||||
|
||||
/**
|
||||
* like DataInputStream.readInt except little endian.
|
||||
*/
|
||||
public final int readInt() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 4);
|
||||
return
|
||||
(w[3]) << 24 |
|
||||
(w[2]&0xff) << 16 |
|
||||
(w[1]&0xff) << 8 |
|
||||
(w[0]&0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* like DataInputStream.readLong except little endian.
|
||||
*/
|
||||
public final long readLong() throws IOException
|
||||
{
|
||||
d.readFully(w, 0, 8);
|
||||
return
|
||||
(long)(w[7]) << 56 |
|
||||
(long)(w[6]&0xff) << 48 |
|
||||
(long)(w[5]&0xff) << 40 |
|
||||
(long)(w[4]&0xff) << 32 |
|
||||
(long)(w[3]&0xff) << 24 |
|
||||
(long)(w[2]&0xff) << 16 |
|
||||
(long)(w[1]&0xff) << 8 |
|
||||
(long)(w[0]&0xff);
|
||||
}
|
||||
|
||||
public final float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
public final double readDouble() throws IOException {
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
public final int read(byte b[], int off, int len) throws IOException {
|
||||
return in.read(b, off, len);
|
||||
}
|
||||
|
||||
public final void readFully(byte b[]) throws IOException {
|
||||
d.readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
public final void readFully(byte b[], int off, int len) throws IOException {
|
||||
d.readFully(b, off, len);
|
||||
}
|
||||
|
||||
public final int skipBytes(int n) throws IOException {
|
||||
return d.skipBytes(n);
|
||||
}
|
||||
|
||||
public final boolean readBoolean() throws IOException {
|
||||
return d.readBoolean();
|
||||
}
|
||||
|
||||
public final byte readByte() throws IOException {
|
||||
return d.readByte();
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
|
||||
public final int readUnsignedByte() throws IOException {
|
||||
return d.readUnsignedByte();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public final String readLine() throws IOException {
|
||||
return d.readLine();
|
||||
}
|
||||
|
||||
public final String readUTF() throws IOException {
|
||||
return d.readUTF();
|
||||
}
|
||||
|
||||
public final void close() throws IOException {
|
||||
d.close();
|
||||
}
|
||||
|
||||
private DataInputStream d; // to get at high level readFully methods of
|
||||
// DataInputStream
|
||||
private InputStream in; // to get at the low-level read methods of
|
||||
// InputStream
|
||||
private byte w[]; // work array for buffering input
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user