package ian.torrent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; // http://wiki.theory.org/BitTorrentSpecification public class Bdecode { private static Map convertToMap(final List list) { final Map m = new HashMap(); final int length = list.size(); for (int i = 0; i < length; i += 2) { final String key = (String) list.get(i); Object value = null; if (i + 1 < length) { value = list.get(i + 1); } m.put(key, value); } return m; } private static List readList(final byte ba[], final int pos[]) throws Exception { final List list = new ArrayList(); char ch = (char) ba[pos[0]]; while (ch != 'e') { if ((ch >= '0') && (ch <= '9')) { int end = pos[0]; ++end; while (ba[end] != ':') { ++end; } final int len = Integer.parseInt(new String(ba, pos[0], end - pos[0])); final String str = new String(ba, end + 1, len); list.add(str); pos[0] = end + len; } else if (ch == 'l') { ++pos[0]; list.add(readList(ba, pos)); } else if (ch == 'd') { ++pos[0]; list.add(convertToMap(readList(ba, pos))); } else if (ch == 'i') { ++pos[0]; int end = pos[0]; while (ba[end] != 'e') { ++end; } list.add(Long.parseLong(new String(ba, pos[0], end - pos[0]))); pos[0] = end; } else { System.out.println("unrecognized " + ch); break; } ++pos[0]; if (pos[0] < ba.length) { ch = (char) ba[pos[0]]; } else { break; } } return list; } public static Map bdecode(final byte ba[]) throws Exception { return convertToMap(readList(ba, new int[] { 1 })); } }