227 lines
5.6 KiB
Java
227 lines
5.6 KiB
Java
package com.frostwire.jlibtorrent;
|
|
|
|
import com.frostwire.jlibtorrent.swig.entry;
|
|
import com.frostwire.jlibtorrent.swig.entry_vector;
|
|
import com.frostwire.jlibtorrent.swig.string_entry_map;
|
|
import com.frostwire.jlibtorrent.swig.string_vector;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.AbstractList;
|
|
import java.util.AbstractMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
/**
|
|
* The Entry class represents one node in a bencoded hierarchy. It works as a
|
|
* variant type, it can be either a list, a dictionary, an integer
|
|
* or a string.
|
|
*
|
|
* @author gubatron
|
|
* @author aldenml
|
|
*/
|
|
public final class Entry {
|
|
|
|
private final entry e;
|
|
|
|
public Entry(entry e) {
|
|
this.e = e;
|
|
}
|
|
|
|
public Entry(String s) {
|
|
this(new entry(s));
|
|
}
|
|
|
|
public Entry(long n) {
|
|
this(new entry(n));
|
|
}
|
|
|
|
public entry swig() {
|
|
return e;
|
|
}
|
|
|
|
public byte[] bencode() {
|
|
return Vectors.byte_vector2bytes(e.bencode());
|
|
}
|
|
|
|
public String string() {
|
|
return e.string();
|
|
}
|
|
|
|
public long integer() {
|
|
return e.integer();
|
|
}
|
|
|
|
public List<Entry> list() {
|
|
return new EntryList(e.list());
|
|
}
|
|
|
|
public Map<String, Entry> dictionary() {
|
|
return new EntryMap(e.dict());
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return e.to_string();
|
|
}
|
|
|
|
public static Entry bdecode(byte[] data) {
|
|
return new Entry(entry.bdecode(Vectors.bytes2byte_vector(data)));
|
|
}
|
|
|
|
public static Entry bdecode(File file) throws IOException {
|
|
byte[] data = Files.bytes(file);
|
|
return bdecode(data);
|
|
}
|
|
|
|
public static Entry fromList(List<?> list) {
|
|
entry e = new entry(entry.data_type.list_t);
|
|
|
|
entry_vector d = e.list();
|
|
for (Object v : list) {
|
|
if (v instanceof String) {
|
|
d.push_back(new entry((String) v));
|
|
} else if (v instanceof Integer) {
|
|
d.push_back(new entry((Integer) v));
|
|
} else if (v instanceof Entry) {
|
|
d.push_back(((Entry) v).swig());
|
|
} else if (v instanceof entry) {
|
|
d.push_back((entry) v);
|
|
} else if (v instanceof List) {
|
|
d.push_back(fromList((List<?>) v).swig());
|
|
} else if (v instanceof Map) {
|
|
d.push_back(fromMap((Map<String, ?>) v).swig());
|
|
} else {
|
|
d.push_back(new entry(v.toString()));
|
|
}
|
|
}
|
|
|
|
return new Entry(e);
|
|
}
|
|
|
|
public static Entry fromMap(Map<String, ?> map) {
|
|
entry e = new entry(entry.data_type.dictionary_t);
|
|
|
|
string_entry_map d = e.dict();
|
|
for (String k : map.keySet()) {
|
|
Object v = map.get(k);
|
|
|
|
if (v instanceof String) {
|
|
d.set(k, new entry((String) v));
|
|
} else if (v instanceof Integer) {
|
|
d.set(k, new entry((Integer) v));
|
|
} else if (v instanceof Entry) {
|
|
d.set(k, ((Entry) v).swig());
|
|
} else if (v instanceof entry) {
|
|
d.set(k, (entry) v);
|
|
} else if (v instanceof List) {
|
|
d.set(k, fromList((List<?>) v).swig());
|
|
} else if (v instanceof Map) {
|
|
d.set(k, fromMap((Map<String, ?>) v).swig());
|
|
} else {
|
|
d.set(k, new entry(v.toString()));
|
|
}
|
|
}
|
|
|
|
return new Entry(e);
|
|
}
|
|
|
|
private static final class EntryList extends AbstractList<Entry> {
|
|
|
|
private final entry_vector v;
|
|
|
|
public EntryList(entry_vector v) {
|
|
this.v = v;
|
|
}
|
|
|
|
@Override
|
|
public Entry get(int index) {
|
|
return new Entry(v.get(index));
|
|
}
|
|
|
|
@Override
|
|
public boolean add(Entry entry) {
|
|
v.push_back(entry.swig());
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return (int) v.size();
|
|
}
|
|
|
|
@Override
|
|
public void clear() {
|
|
v.clear();
|
|
}
|
|
|
|
@Override
|
|
public boolean isEmpty() {
|
|
return v.empty();
|
|
}
|
|
}
|
|
|
|
private static final class EntryMap extends AbstractMap<String, Entry> {
|
|
|
|
private final string_entry_map m;
|
|
|
|
public EntryMap(string_entry_map m) {
|
|
this.m = m;
|
|
}
|
|
|
|
@Override
|
|
public com.frostwire.jlibtorrent.Entry get(Object key) {
|
|
String k = key.toString();
|
|
return m.has_key(k) ? new com.frostwire.jlibtorrent.Entry(m.get(key.toString())) : null;
|
|
}
|
|
|
|
@Override
|
|
public com.frostwire.jlibtorrent.Entry put(String key, com.frostwire.jlibtorrent.Entry value) {
|
|
com.frostwire.jlibtorrent.Entry r = get(key);
|
|
m.set(key, value.swig());
|
|
return r;
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return (int) m.size();
|
|
}
|
|
|
|
@Override
|
|
public void clear() {
|
|
m.clear();
|
|
}
|
|
|
|
@Override
|
|
public boolean containsKey(Object key) {
|
|
return m.has_key(key.toString());
|
|
}
|
|
|
|
@Override
|
|
public boolean isEmpty() {
|
|
return m.empty();
|
|
}
|
|
|
|
@Override
|
|
public Set<String> keySet() {
|
|
HashSet<String> s = new HashSet<>();
|
|
|
|
string_vector v = m.keys();
|
|
int size = (int) v.size();
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
s.add(v.get(i));
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
@Override
|
|
public Set<Entry<String, com.frostwire.jlibtorrent.Entry>> entrySet() {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
}
|
|
}
|