|
|
@ -14,12 +14,11 @@ import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.TreeMap; |
|
|
|
import java.util.TreeMap; |
|
|
|
|
|
|
|
|
|
|
|
public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
public class RencodeInputStream extends FilterInputStream implements DataInput { |
|
|
|
{ |
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The charset that is being used for {@link String}s. |
|
|
|
* The charset that is being used for {@link String}s. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private final String charset; |
|
|
|
private final String charset; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Whether or not all byte-Arrays should be decoded as {@link String}s. |
|
|
|
* Whether or not all byte-Arrays should be decoded as {@link String}s. |
|
|
@ -29,36 +28,31 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Creates a {@link RencodeInputStream} with the default encoding. |
|
|
|
* Creates a {@link RencodeInputStream} with the default encoding. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public RencodeInputStream(InputStream in) |
|
|
|
public RencodeInputStream(InputStream in) { |
|
|
|
{ |
|
|
|
|
|
|
|
this(in, Utils.UTF_8, false); |
|
|
|
this(in, Utils.UTF_8, false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Creates a {@link RencodeInputStream} with the given encoding. |
|
|
|
* Creates a {@link RencodeInputStream} with the given encoding. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public RencodeInputStream(InputStream in, String charset) |
|
|
|
public RencodeInputStream(InputStream in, String charset) { |
|
|
|
{ |
|
|
|
|
|
|
|
this(in, charset, false); |
|
|
|
this(in, charset, false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Creates a {@link RencodeInputStream} with the default encoding. |
|
|
|
* Creates a {@link RencodeInputStream} with the default encoding. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public RencodeInputStream(InputStream in, boolean decodeAsString) |
|
|
|
public RencodeInputStream(InputStream in, boolean decodeAsString) { |
|
|
|
{ |
|
|
|
|
|
|
|
this(in, Utils.UTF_8, decodeAsString); |
|
|
|
this(in, Utils.UTF_8, decodeAsString); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Creates a {@link RencodeInputStream} with the given encoding. |
|
|
|
* Creates a {@link RencodeInputStream} with the given encoding. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public RencodeInputStream(InputStream in, String charset, boolean decodeAsString) |
|
|
|
public RencodeInputStream(InputStream in, String charset, boolean decodeAsString) { |
|
|
|
{ |
|
|
|
|
|
|
|
super(in); |
|
|
|
super(in); |
|
|
|
|
|
|
|
|
|
|
|
if (charset == null) |
|
|
|
if (charset == null) { |
|
|
|
{ |
|
|
|
|
|
|
|
throw new IllegalArgumentException("charset is null"); |
|
|
|
throw new IllegalArgumentException("charset is null"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -70,24 +64,21 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
* Returns the charset that is used to decode {@link String}s. The default |
|
|
|
* Returns the charset that is used to decode {@link String}s. The default |
|
|
|
* value is UTF-8. |
|
|
|
* value is UTF-8. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public String getCharset() |
|
|
|
public String getCharset() { |
|
|
|
{ |
|
|
|
|
|
|
|
return charset; |
|
|
|
return charset; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Returns true if all byte-Arrays are being turned into {@link String}s. |
|
|
|
* Returns true if all byte-Arrays are being turned into {@link String}s. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public boolean isDecodeAsString() |
|
|
|
public boolean isDecodeAsString() { |
|
|
|
{ |
|
|
|
|
|
|
|
return decodeAsString; |
|
|
|
return decodeAsString; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns an {@link Object}. |
|
|
|
* Reads and returns an {@link Object}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Object readObject() throws IOException |
|
|
|
public Object readObject() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
int token = readToken(); |
|
|
|
int token = readToken(); |
|
|
|
|
|
|
|
|
|
|
|
return readObject(token); |
|
|
|
return readObject(token); |
|
|
@ -96,38 +87,22 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns an {@link Object}. |
|
|
|
* Reads and returns an {@link Object}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected Object readObject(int token) throws IOException |
|
|
|
protected Object readObject(int token) throws IOException { |
|
|
|
{ |
|
|
|
if (token == TypeCode.DICTIONARY) { |
|
|
|
if (token == TypeCode.DICTIONARY) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return readMap0(Object.class); |
|
|
|
return readMap0(Object.class); |
|
|
|
} |
|
|
|
} else if (Utils.isFixedDictionary(token)) { |
|
|
|
else if (Utils.isFixedDictionary(token)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return readMap0(Object.class, token); |
|
|
|
return readMap0(Object.class, token); |
|
|
|
} |
|
|
|
} else if (token == TypeCode.LIST) { |
|
|
|
else if (token == TypeCode.LIST) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return readList0(Object.class); |
|
|
|
return readList0(Object.class); |
|
|
|
} |
|
|
|
} else if (Utils.isFixedList(token)) { |
|
|
|
else if (Utils.isFixedList(token)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return readList0(Object.class, token); |
|
|
|
return readList0(Object.class, token); |
|
|
|
} |
|
|
|
} else if (Utils.isNumber(token)) { |
|
|
|
else if (Utils.isNumber(token)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return readNumber0(token); |
|
|
|
return readNumber0(token); |
|
|
|
} |
|
|
|
} else if (token == TypeCode.FALSE || token == TypeCode.TRUE) { |
|
|
|
else if (token == TypeCode.FALSE || token == TypeCode.TRUE) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return readBoolean0(token); |
|
|
|
return readBoolean0(token); |
|
|
|
} |
|
|
|
} else if (token == TypeCode.NULL) { |
|
|
|
else if (token == TypeCode.NULL) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} else if (Utils.isDigit(token) || Utils.isFixedString(token)) { |
|
|
|
else if (Utils.isDigit(token) || Utils.isFixedString(token)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return readString(token, charset); |
|
|
|
return readString(token, charset); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -137,45 +112,38 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns a {@link Map}. |
|
|
|
* Reads and returns a {@link Map}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Map<String, ?> readMap() throws IOException |
|
|
|
public Map<String, ?> readMap() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readMap(Object.class); |
|
|
|
return readMap(Object.class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns a {@link Map}. |
|
|
|
* Reads and returns a {@link Map}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public <T> Map<String, T> readMap(Class<T> clazz) throws IOException |
|
|
|
public <T> Map<String, T> readMap(Class<T> clazz) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
int token = readToken(); |
|
|
|
int token = readToken(); |
|
|
|
|
|
|
|
|
|
|
|
if (token != TypeCode.DICTIONARY) |
|
|
|
if (token != TypeCode.DICTIONARY) { |
|
|
|
{ |
|
|
|
|
|
|
|
throw new IOException(); |
|
|
|
throw new IOException(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return readMap0(clazz); |
|
|
|
return readMap0(clazz); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private <T> Map<String, T> readMap0(Class<T> clazz) throws IOException |
|
|
|
private <T> Map<String, T> readMap0(Class<T> clazz) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
Map<String, T> map = new TreeMap<String, T>(); |
|
|
|
Map<String, T> map = new TreeMap<String, T>(); |
|
|
|
int token = -1; |
|
|
|
int token = -1; |
|
|
|
while ((token = readToken()) != TypeCode.END) |
|
|
|
while ((token = readToken()) != TypeCode.END) { |
|
|
|
{ |
|
|
|
|
|
|
|
readMapItem(clazz, token, map); |
|
|
|
readMapItem(clazz, token, map); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return map; |
|
|
|
return map; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private <T> Map<String, T> readMap0(Class<T> clazz, int token) throws IOException |
|
|
|
private <T> Map<String, T> readMap0(Class<T> clazz, int token) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
Map<String, T> map = new TreeMap<String, T>(); |
|
|
|
Map<String, T> map = new TreeMap<String, T>(); |
|
|
|
|
|
|
|
|
|
|
|
int count = token - TypeCode.EMBEDDED.DICT_START; |
|
|
|
int count = token - TypeCode.EMBEDDED.DICT_START; |
|
|
|
for (int i = 0; i < count; i++) |
|
|
|
for (int i = 0; i < count; i++) { |
|
|
|
{ |
|
|
|
|
|
|
|
readMapItem(clazz, readToken(), map); |
|
|
|
readMapItem(clazz, readToken(), map); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -183,19 +151,16 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private <T> void readMapItem(Class<T> clazz, int token, Map<String, T> map) throws UnsupportedEncodingException, |
|
|
|
private <T> void readMapItem(Class<T> clazz, int token, Map<String, T> map) throws UnsupportedEncodingException, |
|
|
|
IOException |
|
|
|
IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
String key = readString(token, charset); |
|
|
|
String key = readString(token, charset); |
|
|
|
T value = clazz.cast(readObject()); |
|
|
|
T value = clazz.cast(readObject()); |
|
|
|
|
|
|
|
|
|
|
|
map.put(key, value); |
|
|
|
map.put(key, value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public int readToken() throws IOException |
|
|
|
public int readToken() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
int token = super.read(); |
|
|
|
int token = super.read(); |
|
|
|
if (token == -1) |
|
|
|
if (token == -1) { |
|
|
|
{ |
|
|
|
|
|
|
|
throw new EOFException(); |
|
|
|
throw new EOFException(); |
|
|
|
} |
|
|
|
} |
|
|
|
return token; |
|
|
|
return token; |
|
|
@ -204,101 +169,81 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns a {@link List}. |
|
|
|
* Reads and returns a {@link List}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public List<?> readList() throws IOException |
|
|
|
public List<?> readList() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readList(Object.class); |
|
|
|
return readList(Object.class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns a {@link List}. |
|
|
|
* Reads and returns a {@link List}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public <T> List<T> readList(Class<T> clazz) throws IOException |
|
|
|
public <T> List<T> readList(Class<T> clazz) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
int token = readToken(); |
|
|
|
int token = readToken(); |
|
|
|
|
|
|
|
|
|
|
|
if (token != TypeCode.LIST) |
|
|
|
if (token != TypeCode.LIST) { |
|
|
|
{ |
|
|
|
|
|
|
|
throw new IOException(); |
|
|
|
throw new IOException(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return readList0(clazz); |
|
|
|
return readList0(clazz); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private <T> List<T> readList0(Class<T> clazz) throws IOException |
|
|
|
private <T> List<T> readList0(Class<T> clazz) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
List<T> list = new ArrayList<T>(); |
|
|
|
List<T> list = new ArrayList<T>(); |
|
|
|
int token = -1; |
|
|
|
int token = -1; |
|
|
|
while ((token = readToken()) != TypeCode.END) |
|
|
|
while ((token = readToken()) != TypeCode.END) { |
|
|
|
{ |
|
|
|
|
|
|
|
list.add(clazz.cast(readObject(token))); |
|
|
|
list.add(clazz.cast(readObject(token))); |
|
|
|
} |
|
|
|
} |
|
|
|
return list; |
|
|
|
return list; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private <T> List<T> readList0(Class<T> clazz, int token) throws IOException |
|
|
|
private <T> List<T> readList0(Class<T> clazz, int token) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
List<T> list = new ArrayList<T>(); |
|
|
|
List<T> list = new ArrayList<T>(); |
|
|
|
int length = token - TypeCode.EMBEDDED.LIST_START; |
|
|
|
int length = token - TypeCode.EMBEDDED.LIST_START; |
|
|
|
for (int i = 0; i < length; i++) |
|
|
|
for (int i = 0; i < length; i++) { |
|
|
|
{ |
|
|
|
|
|
|
|
list.add(clazz.cast(readObject())); |
|
|
|
list.add(clazz.cast(readObject())); |
|
|
|
} |
|
|
|
} |
|
|
|
return list; |
|
|
|
return list; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public boolean readBoolean() throws IOException |
|
|
|
public boolean readBoolean() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readBoolean0(readToken()); |
|
|
|
return readBoolean0(readToken()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public boolean readBoolean0(int token) throws IOException |
|
|
|
public boolean readBoolean0(int token) throws IOException { |
|
|
|
{ |
|
|
|
if (token == TypeCode.FALSE) { |
|
|
|
if (token == TypeCode.FALSE) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} else if (token == TypeCode.TRUE) { |
|
|
|
else if (token == TypeCode.TRUE) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
throw new IOException(); |
|
|
|
throw new IOException(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public byte readByte() throws IOException |
|
|
|
public byte readByte() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return (byte) readToken(); |
|
|
|
return (byte) readToken(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public char readChar() throws IOException |
|
|
|
public char readChar() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return (char) readToken(); |
|
|
|
return (char) readToken(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public double readDouble() throws IOException |
|
|
|
public double readDouble() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readNumber().doubleValue(); |
|
|
|
return readNumber().doubleValue(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public float readFloat() throws IOException |
|
|
|
public float readFloat() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readNumber().floatValue(); |
|
|
|
return readNumber().floatValue(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void readFully(byte[] dst) throws IOException |
|
|
|
public void readFully(byte[] dst) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
readFully(dst, 0, dst.length); |
|
|
|
readFully(dst, 0, dst.length); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void readFully(byte[] dst, int off, int len) throws IOException |
|
|
|
public void readFully(byte[] dst, int off, int len) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
int total = 0; |
|
|
|
int total = 0; |
|
|
|
|
|
|
|
|
|
|
|
while (total < len) |
|
|
|
while (total < len) { |
|
|
|
{ |
|
|
|
|
|
|
|
int r = read(dst, total, len - total); |
|
|
|
int r = read(dst, total, len - total); |
|
|
|
if (r == -1) |
|
|
|
if (r == -1) { |
|
|
|
{ |
|
|
|
|
|
|
|
throw new EOFException(); |
|
|
|
throw new EOFException(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -306,60 +251,49 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public int readInt() throws IOException |
|
|
|
public int readInt() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readNumber().intValue(); |
|
|
|
return readNumber().intValue(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String readLine() throws IOException |
|
|
|
public String readLine() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readString(); |
|
|
|
return readString(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public long readLong() throws IOException |
|
|
|
public long readLong() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readNumber().longValue(); |
|
|
|
return readNumber().longValue(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public short readShort() throws IOException |
|
|
|
public short readShort() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readNumber().shortValue(); |
|
|
|
return readNumber().shortValue(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String readUTF() throws IOException |
|
|
|
public String readUTF() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readString(Utils.UTF_8); |
|
|
|
return readString(Utils.UTF_8); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public int readUnsignedByte() throws IOException |
|
|
|
public int readUnsignedByte() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readByte() & 0xFF; |
|
|
|
return readByte() & 0xFF; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public int readUnsignedShort() throws IOException |
|
|
|
public int readUnsignedShort() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readShort() & 0xFFFF; |
|
|
|
return readShort() & 0xFFFF; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns a {@link Number}. |
|
|
|
* Reads and returns a {@link Number}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public Number readNumber() throws IOException |
|
|
|
public Number readNumber() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
int token = readToken(); |
|
|
|
int token = readToken(); |
|
|
|
|
|
|
|
|
|
|
|
if (!Utils.isNumber(token)) |
|
|
|
if (!Utils.isNumber(token)) { |
|
|
|
{ |
|
|
|
|
|
|
|
throw new IOException(); |
|
|
|
throw new IOException(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return readNumber0(token); |
|
|
|
return readNumber0(token); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Number readNumber0(int token) throws IOException |
|
|
|
private Number readNumber0(int token) throws IOException { |
|
|
|
{ |
|
|
|
switch (token) { |
|
|
|
switch (token) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case TypeCode.BYTE: |
|
|
|
case TypeCode.BYTE: |
|
|
|
return (int) readToBuffer(1).get(); |
|
|
|
return (int) readToBuffer(1).get(); |
|
|
|
case TypeCode.SHORT: |
|
|
|
case TypeCode.SHORT: |
|
|
@ -376,67 +310,52 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
case TypeCode.NUMBER: |
|
|
|
case TypeCode.NUMBER: |
|
|
|
return readNumber0(); |
|
|
|
return readNumber0(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (Utils.isNegativeFixedNumber(token)) |
|
|
|
if (Utils.isNegativeFixedNumber(token)) { |
|
|
|
{ |
|
|
|
|
|
|
|
return TypeCode.EMBEDDED.INT_NEG_START - 1 - token; |
|
|
|
return TypeCode.EMBEDDED.INT_NEG_START - 1 - token; |
|
|
|
} |
|
|
|
} else if (Utils.isPositiveFixedNumber(token)) { |
|
|
|
else if (Utils.isPositiveFixedNumber(token)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return TypeCode.EMBEDDED.INT_POS_START + token; |
|
|
|
return TypeCode.EMBEDDED.INT_POS_START + token; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
throw new IOException("Unknown number. TypeCode: " + token); |
|
|
|
throw new IOException("Unknown number. TypeCode: " + token); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private ByteBuffer readToBuffer(int count) throws IOException |
|
|
|
private ByteBuffer readToBuffer(int count) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return ByteBuffer.wrap(readBytesFixed(count)); |
|
|
|
return ByteBuffer.wrap(readBytesFixed(count)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Number readNumber0() throws IOException |
|
|
|
private Number readNumber0() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
StringBuilder buffer = new StringBuilder(); |
|
|
|
StringBuilder buffer = new StringBuilder(); |
|
|
|
|
|
|
|
|
|
|
|
boolean decimal = false; |
|
|
|
boolean decimal = false; |
|
|
|
|
|
|
|
|
|
|
|
int token = -1; |
|
|
|
int token = -1; |
|
|
|
while ((token = readToken()) != TypeCode.END) |
|
|
|
while ((token = readToken()) != TypeCode.END) { |
|
|
|
{ |
|
|
|
if (token == '.') { |
|
|
|
if (token == '.') |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
decimal = true; |
|
|
|
decimal = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
buffer.append((char) token); |
|
|
|
buffer.append((char) token); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
try |
|
|
|
try { |
|
|
|
{ |
|
|
|
if (decimal) { |
|
|
|
if (decimal) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return new BigDecimal(buffer.toString()); |
|
|
|
return new BigDecimal(buffer.toString()); |
|
|
|
} |
|
|
|
} else { |
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return new BigInteger(buffer.toString()); |
|
|
|
return new BigInteger(buffer.toString()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (NumberFormatException err) { |
|
|
|
catch (NumberFormatException err) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
throw new IOException("NumberFormatException", err); |
|
|
|
throw new IOException("NumberFormatException", err); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public int skipBytes(int n) throws IOException |
|
|
|
public int skipBytes(int n) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return (int) skip(n); |
|
|
|
return (int) skip(n); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns a byte-Array. |
|
|
|
* Reads and returns a byte-Array. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public byte[] readBytes() throws IOException |
|
|
|
public byte[] readBytes() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
int token = readToken(); |
|
|
|
int token = readToken(); |
|
|
|
|
|
|
|
|
|
|
|
return readBytes(token); |
|
|
|
return readBytes(token); |
|
|
@ -445,46 +364,38 @@ public class RencodeInputStream extends FilterInputStream implements DataInput |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reads and returns a {@link String}. |
|
|
|
* Reads and returns a {@link String}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public String readString() throws IOException |
|
|
|
public String readString() throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readString(charset); |
|
|
|
return readString(charset); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private String readString(String encoding) throws IOException |
|
|
|
private String readString(String encoding) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
return readString(readToken(), encoding); |
|
|
|
return readString(readToken(), encoding); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private String readString(int token, String charset) throws IOException |
|
|
|
private String readString(int token, String charset) throws IOException { |
|
|
|
{ |
|
|
|
if (Utils.isFixedString(token)) { |
|
|
|
if (Utils.isFixedString(token)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int length = token - TypeCode.EMBEDDED.STR_START; |
|
|
|
int length = token - TypeCode.EMBEDDED.STR_START; |
|
|
|
return new String(readBytesFixed(length), charset); |
|
|
|
return new String(readBytesFixed(length), charset); |
|
|
|
} |
|
|
|
} |
|
|
|
return new String(readBytes(token), charset); |
|
|
|
return new String(readBytes(token), charset); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private byte[] readBytes(int token) throws IOException |
|
|
|
private byte[] readBytes(int token) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
int length = readLength(token); |
|
|
|
int length = readLength(token); |
|
|
|
return readBytesFixed(length); |
|
|
|
return readBytesFixed(length); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private byte[] readBytesFixed(int count) throws IOException |
|
|
|
private byte[] readBytesFixed(int count) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
byte[] data = new byte[count]; |
|
|
|
byte[] data = new byte[count]; |
|
|
|
readFully(data); |
|
|
|
readFully(data); |
|
|
|
return data; |
|
|
|
return data; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private int readLength(int token) throws IOException |
|
|
|
private int readLength(int token) throws IOException { |
|
|
|
{ |
|
|
|
|
|
|
|
StringBuilder buffer = new StringBuilder(); |
|
|
|
StringBuilder buffer = new StringBuilder(); |
|
|
|
buffer.append((char) token); |
|
|
|
buffer.append((char) token); |
|
|
|
|
|
|
|
|
|
|
|
while ((token = readToken()) != TypeCode.LENGTH_DELIM) |
|
|
|
while ((token = readToken()) != TypeCode.LENGTH_DELIM) { |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buffer.append((char) token); |
|
|
|
buffer.append((char) token); |
|
|
|
} |
|
|
|
} |
|
|
|