panda.net.p2p.Torrent Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of panda-nets Show documentation
Show all versions of panda-nets Show documentation
Panda Nets is a client side library of many basic Internet protocols.
package panda.net.p2p;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import panda.cast.Castors;
import panda.codec.binary.Base32;
import panda.io.stream.ByteArrayOutputStream;
import panda.lang.Charsets;
import panda.lang.Collections;
import panda.lang.Strings;
import panda.lang.reflect.Types;
import panda.util.crypto.Digests;
public class Torrent {
public static class Item {
public long length;
public String path;
}
public static String getBtih(byte[] bs) throws IOException {
return new Torrent(bs).getBtih();
}
public static String getBtih(InputStream is) throws IOException {
return new Torrent(is).getBtih();
}
private String encoding = Charsets.UTF_8;
private String name;
private String btih;
private List- files;
private long length;
private Map
root;
public Torrent() {
}
public Torrent(InputStream is) throws IOException {
parse(is);
}
public Torrent(byte[] bs) throws IOException {
parse(bs);
}
/**
* @return the encoding
*/
public String getEncoding() {
return encoding;
}
/**
* @param encoding the encoding to set
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* @return the btih
*/
public String getBtih() {
return btih;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the length
*/
public long getLength() {
return length;
}
/**
* @param length the length to set
*/
public void setLength(long length) {
this.length = length;
}
/**
* @return the files
*/
public List- getFiles() {
return files;
}
/**
* @param files the files to set
*/
public void setFiles(List
- files) {
this.files = files;
}
/**
* @return single file or not
*/
public boolean isSingle() {
return files == null;
}
/**
* @return the root
*/
public Map
root() {
return root;
}
private String getPropertyAsString(Map map, String key) {
return getPropertyAsString(map, key, null);
}
private String getPropertyAsString(Map map, String key, String def) {
Object v = map.get(key);
if (v instanceof byte[]) {
return Strings.newString((byte[])v, encoding);
}
return v == null ? def : v.toString();
}
private void parse(byte[] bs) throws IOException {
InputStream is = new ByteArrayInputStream(bs);
parse(is);
}
@SuppressWarnings("unchecked")
private void parse(InputStream is) throws IOException {
root = (Map)Bencode.parse(is);
Map info = (Map)(root.get("info"));
if (Collections.isEmpty(info)) {
throw new IOException("Invalid torrent file: missing ");
}
encoding = getPropertyAsString(info, "encoding", encoding);
name = getPropertyAsString(info, "name");
if (info.containsKey("length")) {
length = (Long)info.get("length");
}
else {
List files = (List)(info.get("files"));
if (Collections.isEmpty(files)) {
throw new IOException("Invalid torrent file: missing or ");
}
this.files = Castors.scast(files, Types.paramTypeOf(List.class, Item.class), false);
length = 0;
for (Item i : this.files) {
length += i.length;
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bencode.write(info, baos);
byte[] sha1 = Digests.sha1(baos.toByteArray());
btih = Base32.encodeBase32String(sha1);
}
public String toMagnetURL() {
Magnet mag = new Magnet();
mag.setDn(name);
mag.setBtih(btih);
return mag.toURL();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy