From f075667a0d40961d36822a79b1f689ab3dde7683 Mon Sep 17 00:00:00 2001 From: Marcin Cieslak Date: Fri, 22 May 2015 08:57:05 +0000 Subject: [PATCH] InputStream does not need support mark/reset Use lookahead variable to avoid using mark()/reset() on the java.io.InputStream --- .../org/bitlet/wetorrent/bencode/Bencode.java | 79 ++++++++----------- 1 file changed, 33 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/bitlet/wetorrent/bencode/Bencode.java b/src/main/java/org/bitlet/wetorrent/bencode/Bencode.java index c2b203d..731e9b4 100644 --- a/src/main/java/org/bitlet/wetorrent/bencode/Bencode.java +++ b/src/main/java/org/bitlet/wetorrent/bencode/Bencode.java @@ -40,10 +40,7 @@ public class Bencode { * This creates and parse a bencoded InputStream */ public Bencode(InputStream is) throws IOException { - if (!is.markSupported()) { - throw new IOException("is.markSupported should be true"); - } - rootElement = parse(is); + rootElement = parse(readHead(is), is); } /** @@ -100,16 +97,18 @@ private void print(Object object, OutputStream os) throws IOException { } } - private Object parse(InputStream is) throws IOException { - is.mark(0); - int readChar = is.read(); - switch (readChar) { + private int readHead(InputStream is) throws IOException { + return is.read(); + } + + private Object parse(int head, InputStream tail) throws IOException { + switch (head) { case 'i': - return parseInteger(is); + return parseInteger(readHead(tail), tail); case 'l': - return parseList(is); + return parseList(readHead(tail), tail); case 'd': - return parseDictionary(is); + return parseDictionary(readHead(tail), tail); case '0': case '1': case '2': @@ -120,8 +119,7 @@ private Object parse(InputStream is) throws IOException { case '7': case '8': case '9': - is.reset(); - return parseByteString(is); + return parseByteString(head, tail); default: throw new IOException("Problem parsing bencoded file"); } @@ -135,75 +133,64 @@ public void setRootElement(Object rootElement) { this.rootElement = rootElement; } - private Long parseInteger(InputStream is) throws IOException { - - int readChar = is.read(); + private Long parseInteger(int head, InputStream tail) throws IOException { StringBuffer buff = new StringBuffer(); do { - if (readChar < 0) { + if (head < 0) { throw new IOException("Unexpected EOF found"); } - buff.append((char) readChar); - readChar = is.read(); - } while (readChar != 'e'); + buff.append((char) head); + head = readHead(tail); + } while (head != 'e'); // System.out.println("Loaded int: " + buff); return Long.parseLong(buff.toString()); } - private List parseList(InputStream is) throws IOException { + private List parseList(int head, InputStream tail) throws IOException { List list = new LinkedList(); - is.mark(0); - int readChar = is.read(); - while (readChar != 'e') { - if (readChar < 0) { + while (head != 'e') { + if (head < 0) { throw new IOException("Unexpected EOF found"); } - is.reset(); - list.add(parse(is)); - is.mark(0); - readChar = is.read(); + list.add(parse(head, tail)); + head = readHead(tail); } return list; } - private SortedMap parseDictionary(InputStream is) throws IOException { + private SortedMap parseDictionary(int head, InputStream tail) throws IOException { SortedMap map = new TreeMap(new DictionaryComparator()); - is.mark(0); - int readChar = is.read(); - while (readChar != 'e') { - if (readChar < 0) { + while (head != 'e') { + if (head < 0) { throw new IOException("Unexpected EOF found"); } - is.reset(); - map.put(parseByteString(is), parse(is)); - is.mark(0); - readChar = is.read(); + ByteBuffer key = parseByteString(head, tail); + map.put(key, parse(readHead(tail), tail)); + head = readHead(tail); } return map; } - private ByteBuffer parseByteString(InputStream is) throws IOException { - - int readChar = is.read(); + private ByteBuffer parseByteString(int head, InputStream tail) throws IOException { StringBuffer buff = new StringBuffer(); do { - if (readChar < 0) { + if (head < 0) { throw new IOException("Unexpected EOF found"); } - buff.append((char) readChar); - readChar = is.read(); - } while (readChar != ':'); + buff.append((char) head); + head = readHead(tail); + } while (head != ':'); Integer length = Integer.parseInt(buff.toString()); byte[] byteString = new byte[length]; for (int i = 0; i < byteString.length; i++) { - byteString[i] = (byte) is.read(); + byteString[i] = (byte) readHead(tail); // System.out.println("Loaded string: " + new String(byteString)); } return ByteBuffer.wrap(byteString);