This commit is contained in:
Ziver Koc 2009-01-13 00:48:46 +00:00
parent d699626cf0
commit 9e3de28d45
3 changed files with 216 additions and 0 deletions

View file

@ -1,6 +1,9 @@
package zutil;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
@ -52,6 +55,28 @@ public class FileFinder {
return null;
}
/**
* Reads and returns the content of a file as a String.
* Or use FileUtils.readFileToString(file);
*
* @param file The file to read
* @return The file content
* @throws IOException
*/
public static String getFileContent(File file) throws IOException{
BufferedReader in = new BufferedReader(new FileReader(file));
StringBuffer ret = new StringBuffer();
int tmp;
while((tmp=in.read()) != -1){
ret.append((char)tmp);
}
in.close();
return ret.toString();
}
/**
* Returns the URL to the given file
*

View file

@ -0,0 +1,68 @@
package zutil.network.torrent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import zutil.FileFinder;
public class Torrent {
// Name of the torrent
private String name;
// Comment
private String comment;
// Creation date as unix timestamp
private long date;
// Files in the torrent
private ArrayList<String> file_list;
// Size of of the full torrent (after download)
private long size;
// Signature of the software which created the torrent
private String created_by;
// tracker (the tracker the torrent has been received from)
private String main_tracker;
// List of known trackers for the torrent
private ArrayList<String> tracker_list;
private HashMap<String,Object> info_hash;
// Torrent is marked as 'private'.
private boolean is_private;
public Torrent(File torrent) throws IOException{
this(FileFinder.getFileContent(FileFinder.find("C:\\Users\\Ziver\\Desktop\\test.torrent")));
}
public Torrent(String data){
reset();
decode(data);
}
private void reset(){
// Reset
name = "";
comment = "";
date = 0;
file_list = new ArrayList<String>();
size = 0;
created_by = "";
main_tracker = "";
tracker_list = new ArrayList<String>();
info_hash = new HashMap<String,Object>();
is_private = false;
}
private void decode(String data){
HashMap dataMap = (HashMap)TorrentParser.decode(data);
name = (String)dataMap.get("name");
comment = (String)dataMap.get("comment");
date = (Long)dataMap.get("creation date");
file_list = new ArrayList<String>();
size = (Long)dataMap.get("length");
created_by = (String)dataMap.get("created by");
main_tracker = (String)dataMap.get("announce");
tracker_list = (ArrayList<String>)dataMap.get("announce-list");
info_hash = (HashMap)dataMap.get("info");
is_private = (((Integer)dataMap.get("private")) != 0);
}
}

View file

@ -0,0 +1,123 @@
package zutil.network.torrent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import zutil.FileFinder;
import zutil.MultiPrintStream;
/**
* http://wiki.theory.org/BitTorrentSpecification
* @author Ziver
*
*/
public class TorrentParser {
/**
* Example use
*/
public static void main(String[] args){
try {
String tmp = FileFinder.getFileContent(FileFinder.find("C:\\Users\\Ziver\\Desktop\\test.torrent"));
MultiPrintStream.out.dump(TorrentParser.decode(tmp));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns the representation of the data in the BEncoded string
*
* @param data The data to be decoded
* @return
*/
public static Object decode(String data){
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
*/
@SuppressWarnings("unchecked")
private static Object decode_BEncoded(StringBuffer data){
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);
return new Long(tmp);
/**
* 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);
LinkedList list = new LinkedList();
c = data.charAt(0);
while(c != 'e'){
list.add(decode_BEncoded(data));
c = data.charAt(0);
}
data.deleteCharAt(0);
//MultiPrintStream.out.dump(list);
if(list.size() == 1) return list.poll();
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);
HashMap map = new HashMap();
c = data.charAt(0);
while(c != 'e'){
Object tmp2 = decode_BEncoded(data);
map.put(tmp2, decode_BEncoded(data));
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));
return ret;
}
}
}