hal/src/zutil/parser/BEncodedParser.java

123 lines
4.3 KiB
Java
Raw Normal View History

2011-07-13 17:53:17 +00:00
/*******************************************************************************
* Copyright (c) 2011 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
2011-06-24 23:20:59 +00:00
package zutil.parser;
2009-01-13 00:48:46 +00:00
2011-06-24 23:20:59 +00:00
import zutil.parser.DataNode.DataType;
2009-01-13 00:48:46 +00:00
/**
* http://wiki.theory.org/BitTorrentSpecification
* @author Ziver
*
*/
2011-06-24 23:20:59 +00:00
public class BEncodedParser {
2009-01-13 00:48:46 +00:00
/**
* Returns the representation of the data in the BEncoded string
*
* @param data The data to be decoded
* @return
*/
2011-06-24 23:20:59 +00:00
public static DataNode parse(String data){
2009-01-13 00:48:46 +00:00
return decode_BEncoded(new StringBuffer(data));
}
/**
* Returns the representation of the data in the BEncoded string
*
* @param data The data to be decoded
* @param index The index in data to start from
* @return
*/
2011-06-24 23:20:59 +00:00
private static DataNode decode_BEncoded(StringBuffer data){
2009-01-13 00:48:46 +00:00
String tmp;
char c = ' ';
switch (data.charAt(0)) {
/**
* Integers are prefixed with an i and terminated by an e. For
* example, 123 would bEcode to i123e, -3272002 would bEncode to
* i-3272002e.
*/
case 'i':
//System.out.println("Found Integer at "+index);
data.deleteCharAt(0);
tmp = data.substring(0, data.indexOf("e"));
data.delete(0, tmp.length() + 1);
//System.out.println(tmp);
2011-06-24 23:20:59 +00:00
return new DataNode( new Long(tmp));
2009-01-13 00:48:46 +00:00
/**
* Lists are prefixed with a l and terminated by an e. The list
* should contain a series of bEncoded elements. For example, the
* list of strings ["Monduna", "Bit", "Torrents"] would bEncode to
* l7:Monduna3:Bit8:Torrentse. The list [1, "Monduna", 3, ["Sub", "List"]]
* would bEncode to li1e7:Mondunai3el3:Sub4:Listee
*/
case 'l':
//System.out.println("Found List at "+index);
data.deleteCharAt(0);
2011-06-24 23:20:59 +00:00
DataNode list = new DataNode( DataType.List );
2009-01-13 00:48:46 +00:00
c = data.charAt(0);
while(c != 'e'){
2011-06-24 23:20:59 +00:00
list.add( decode_BEncoded(data) );
2009-01-13 00:48:46 +00:00
c = data.charAt(0);
}
data.deleteCharAt(0);
//MultiPrintStream.out.dump(list);
2011-06-24 23:20:59 +00:00
if(list.size() == 1) return list.get(0);
2009-01-13 00:48:46 +00:00
else return list;
/**
* Dictionaries are prefixed with a d and terminated by an e. They
* are similar to list, except that items are in key value pairs. The
* dictionary {"key":"value", "Monduna":"com", "bit":"Torrents", "number":7}
* would bEncode to d3:key5:value7:Monduna3:com3:bit:8:Torrents6:numberi7ee
*/
case 'd':
//System.out.println("Found Dictionary at "+index);
data.deleteCharAt(0);
2011-06-24 23:20:59 +00:00
DataNode map = new DataNode( DataType.Map );
2009-01-13 00:48:46 +00:00
c = data.charAt(0);
while(c != 'e'){
2011-06-24 23:20:59 +00:00
DataNode tmp2 = decode_BEncoded(data);
map.set(tmp2.getString(), decode_BEncoded(data));
2009-01-13 00:48:46 +00:00
c = data.charAt(0);
}
data.deleteCharAt(0);
//MultiPrintStream.out.dump(map);
return map;
/**
* Strings are prefixed with their length followed by a colon.
* For example, "Monduna" would bEncode to 7:Monduna and "BitTorrents"
* would bEncode to 11:BitTorrents.
*/
default:
//System.out.println("Found String at "+index);
tmp = data.substring(0, data.indexOf(":"));
int length = Integer.parseInt(tmp);
data.delete(0, tmp.length()+1);
String ret = data.substring(0, length);
data.delete(0, length);
//System.out.println(data.substring(i, i+length));
2011-06-24 23:20:59 +00:00
return new DataNode( ret );
2009-01-13 00:48:46 +00:00
}
}
}