📄 bencoder.java
字号:
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: BEncoder.java
package org.gudy.azureus2.core3.util;
import java.io.*;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.*;
import org.gudy.azureus2.core3.xml.util.XUXmlWriter;
// Referenced classes of package org.gudy.azureus2.core3.util:
// ByteEncodedKeyHashMap, Constants, Debug
public class BEncoder
{
protected static class XMLEncoder extends XUXmlWriter
{
protected StringBuffer encode(Map map, boolean simple)
{
StringWriter writer = new StringWriter(1024);
setOutputWriter(writer);
setGenericSimple(simple);
writeGeneric(map);
flushOutputStream();
return writer.getBuffer();
}
protected XMLEncoder()
{
}
}
private static final int BUFFER_DOUBLE_LIMIT = 0x40000;
private static final byte MINUS_1_BYTES[] = "-1".getBytes();
private byte current_buffer[];
private int current_buffer_pos;
private byte old_buffers[][];
private byte int_buffer[];
private boolean url_encode;
static final byte digits[] = {
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122
};
static final byte DigitTens[] = {
48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
57, 57, 57, 57, 57, 57, 57, 57, 57, 57
};
static final byte DigitOnes[] = {
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57
};
public static byte[] encode(Map object)
throws IOException
{
return encode(object, false);
}
public static byte[] encode(Map object, boolean url_encode)
throws IOException
{
BEncoder encoder = new BEncoder(url_encode);
encoder.encodeObject(object);
return encoder.toByteArray();
}
private BEncoder(boolean _url_encode)
{
current_buffer = new byte[256];
current_buffer_pos = 0;
int_buffer = new byte[12];
url_encode = _url_encode;
}
private boolean encodeObject(Object object)
throws IOException
{
if ((object instanceof String) || (object instanceof Float))
{
String tempString = (object instanceof String) ? (String)object : String.valueOf((Float)object);
boolean simple = true;
char chars[] = tempString.toCharArray();
int char_count = chars.length;
byte encoded[] = new byte[char_count];
int i = 0;
do
{
if (i >= char_count)
break;
char c = chars[i];
if (c < '\200')
{
encoded[i] = (byte)c;
} else
{
simple = false;
break;
}
i++;
} while (true);
if (simple)
{
writeInt(char_count);
writeChar(':');
writeBytes(encoded);
} else
{
ByteBuffer bb = Constants.DEFAULT_CHARSET.encode(tempString);
writeInt(bb.limit());
writeChar(':');
writeByteBuffer(bb);
}
} else
if (object instanceof Map)
{
Map tempMap = (Map)object;
SortedMap tempTree = null;
boolean byte_keys = object instanceof ByteEncodedKeyHashMap;
writeChar('d');
if (tempMap instanceof TreeMap)
tempTree = (TreeMap)tempMap;
else
tempTree = new TreeMap(tempMap);
Iterator it = tempTree.entrySet().iterator();
do
{
if (!it.hasNext())
break;
java.util.Map.Entry entry = (java.util.Map.Entry)it.next();
Object o_key = entry.getKey();
Object value = entry.getValue();
if (value != null)
if (o_key instanceof byte[])
{
encodeObject(o_key);
if (!encodeObject(value))
encodeObject("");
} else
if (o_key instanceof String)
{
String key = (String)o_key;
if (byte_keys)
{
try
{
encodeObject(Constants.BYTE_CHARSET.encode(key));
if (!encodeObject(tempMap.get(key)))
encodeObject("");
}
catch (UnsupportedEncodingException e)
{
throw new IOException((new StringBuilder()).append("BEncoder: unsupport encoding: ").append(e.getMessage()).toString());
}
} else
{
encodeObject(key);
if (!encodeObject(value))
encodeObject("");
}
} else
{
Debug.out((new StringBuilder()).append("Attempt to encode an unsupported map key type: ").append(object.getClass()).append(";value=").append(object).toString());
}
} while (true);
writeChar('e');
} else
if (object instanceof List)
{
List tempList = (List)object;
writeChar('l');
for (int i = 0; i < tempList.size(); i++)
encodeObject(tempList.get(i));
writeChar('e');
} else
if (object instanceof Long)
{
Long tempLong = (Long)object;
writeChar('i');
writeLong(tempLong.longValue());
writeChar('e');
} else
if (object instanceof Integer)
{
Integer tempInteger = (Integer)object;
writeChar('i');
writeInt(tempInteger.intValue());
writeChar('e');
} else
if (object instanceof byte[])
{
byte tempByteArray[] = (byte[])(byte[])object;
writeInt(tempByteArray.length);
writeChar(':');
if (url_encode)
writeBytes(URLEncoder.encode(new String(tempByteArray, "ISO-8859-1"), "ISO-8859-1").getBytes());
else
writeBytes(tempByteArray);
} else
if (object instanceof ByteBuffer)
{
ByteBuffer bb = (ByteBuffer)object;
writeInt(bb.limit());
writeChar(':');
writeByteBuffer(bb);
} else
if (object == null)
{
Debug.out("Attempt to encode a null value");
return false;
} else
{
Debug.out((new StringBuilder()).append("Attempt to encode an unsupported entry type: ").append(object.getClass()).append(";value=").append(object).toString());
return false;
}
return true;
}
private void writeChar(char c)
{
int rem = current_buffer.length - current_buffer_pos;
if (rem > 0)
{
current_buffer[current_buffer_pos++] = (byte)c;
} else
{
int next_buffer_size = current_buffer.length >= 0x40000 ? current_buffer.length + 0x40000 : current_buffer.length << 1;
byte new_buffer[] = new byte[next_buffer_size];
new_buffer[0] = (byte)c;
if (old_buffers == null)
{
old_buffers = (new byte[][] {
current_buffer
});
} else
{
byte new_old_buffers[][] = new byte[old_buffers.length + 1][];
System.arraycopy(old_buffers, 0, new_old_buffers, 0, old_buffers.length);
new_old_buffers[old_buffers.length] = current_buffer;
old_buffers = new_old_buffers;
}
current_buffer = new_buffer;
current_buffer_pos = 1;
}
}
private void writeInt(int i)
{
if (i == -1)
{
writeBytes(MINUS_1_BYTES);
return;
} else
{
int start = intToBytes(i);
writeBytes(int_buffer, start, 12 - start);
return;
}
}
private void writeLong(long l)
{
if (l <= 0x7fffffffL && l >= 0xffffffff80000000L)
writeInt((int)l);
else
writeBytes(Long.toString(l).getBytes());
}
private void writeBytes(byte bytes[])
{
writeBytes(bytes, 0, bytes.length);
}
private void writeBytes(byte bytes[], int offset, int length)
{
int rem = current_buffer.length - current_buffer_pos;
if (rem >= length)
{
System.arraycopy(bytes, offset, current_buffer, current_buffer_pos, length);
current_buffer_pos += length;
} else
{
if (rem > 0)
{
System.arraycopy(bytes, offset, current_buffer, current_buffer_pos, rem);
length -= rem;
}
int next_buffer_size = current_buffer.length >= 0x40000 ? current_buffer.length + 0x40000 : current_buffer.length << 1;
byte new_buffer[] = new byte[Math.max(next_buffer_size, length + 512)];
System.arraycopy(bytes, offset + rem, new_buffer, 0, length);
if (old_buffers == null)
{
old_buffers = (new byte[][] {
current_buffer
});
} else
{
byte new_old_buffers[][] = new byte[old_buffers.length + 1][];
System.arraycopy(old_buffers, 0, new_old_buffers, 0, old_buffers.length);
new_old_buffers[old_buffers.length] = current_buffer;
old_buffers = new_old_buffers;
}
current_buffer = new_buffer;
current_buffer_pos = length;
}
}
private void writeByteBuffer(ByteBuffer bb)
{
writeBytes(bb.array(), bb.arrayOffset() + bb.position(), bb.remaining());
}
private byte[] toByteArray()
{
if (old_buffers == null)
{
byte res[] = new byte[current_buffer_pos];
System.arraycopy(current_buffer, 0, res, 0, current_buffer_pos);
return res;
}
int total = current_buffer_pos;
for (int i = 0; i < old_buffers.length; i++)
total += old_buffers[i].length;
byte res[] = new byte[total];
int pos = 0;
for (int i = 0; i < old_buffers.length; i++)
{
byte buffer[] = old_buffers[i];
int len = buffer.length;
System.arraycopy(buffer, 0, res, pos, len);
pos += len;
}
System.arraycopy(current_buffer, 0, res, pos, current_buffer_pos);
return res;
}
private static Object normaliseObject(Object o)
{
if (o instanceof Integer)
o = new Long(((Integer)o).longValue());
else
if (o instanceof Boolean)
o = new Long(((Boolean)o).booleanValue() ? 1L : 0L);
else
if (o instanceof Float)
o = String.valueOf((Float)o);
else
if (o instanceof byte[])
try
{
o = new String((byte[])(byte[])o, "UTF-8");
}
catch (Throwable e) { }
return o;
}
public static boolean isEncodable(Object toCheck)
{
if ((toCheck instanceof Integer) || (toCheck instanceof Long) || (toCheck instanceof Boolean) || (toCheck instanceof Float) || (toCheck instanceof byte[]) || (toCheck instanceof String))
return true;
if (toCheck instanceof Map)
{
for (Iterator it = ((Map)toCheck).keySet().iterator(); it.hasNext();)
{
java.util.Map.Entry entry = (java.util.Map.Entry)it.next();
Object key = entry.getKey();
if (!(key instanceof String) && !(key instanceof byte[]) || !isEncodable(entry.getValue()))
return false;
}
return true;
}
if (toCheck instanceof List)
{
for (Iterator it = ((List)toCheck).iterator(); it.hasNext();)
if (!isEncodable(it.next()))
return false;
return true;
} else
{
return false;
}
}
public static boolean objectsAreIdentical(Object o1, Object o2)
{
if (o1 == null && o2 == null)
return true;
if (o1 == null || o2 == null)
return false;
if (o1.getClass() != o2.getClass() && (!(o1 instanceof Map) || !(o2 instanceof Map)) && (!(o1 instanceof List) || !(o2 instanceof List)))
{
o1 = normaliseObject(o1);
o2 = normaliseObject(o2);
if (o1.getClass() != o2.getClass())
{
Debug.out((new StringBuilder()).append("Failed to normalise classes ").append(o1.getClass()).append("/").append(o2.getClass()).toString());
return false;
}
}
if ((o1 instanceof Long) || (o1 instanceof String))
return o1.equals(o2);
if (o1 instanceof byte[])
return Arrays.equals((byte[])(byte[])o1, (byte[])(byte[])o2);
if (o1 instanceof List)
return listsAreIdentical((List)o1, (List)o2);
if (o1 instanceof Map)
return mapsAreIdentical((Map)o1, (Map)o2);
if ((o1 instanceof Integer) || (o1 instanceof Boolean) || (o1 instanceof Float) || (o1 instanceof ByteBuffer))
{
return o1.equals(o2);
} else
{
Debug.out((new StringBuilder()).append("Invalid type: ").append(o1).toString());
return false;
}
}
public static boolean listsAreIdentical(List list1, List list2)
{
if (list1 == null && list2 == null)
return true;
if (list1 == null || list2 == null)
return false;
if (list1.size() != list2.size())
return false;
for (int i = 0; i < list1.size(); i++)
if (!objectsAreIdentical(list1.get(i), list2.get(i)))
return false;
return true;
}
public static boolean mapsAreIdentical(Map map1, Map map2)
{
if (map1 == null && map2 == null)
return true;
if (map1 == null || map2 == null)
return false;
if (map1.size() != map2.size())
return false;
for (Iterator it = map1.keySet().iterator(); it.hasNext();)
{
Object key = it.next();
Object v1 = map1.get(key);
Object v2 = map2.get(key);
if (!objectsAreIdentical(v1, v2))
return false;
}
return true;
}
public static Map cloneMap(Map map)
{
if (map == null)
return null;
Map res = new TreeMap();
Object key;
Object value;
for (Iterator it = map.entrySet().iterator(); it.hasNext(); res.put(key, clone(value)))
{
java.util.Map.Entry entry = (java.util.Map.Entry)it.next();
key = entry.getKey();
value = entry.getValue();
if (key instanceof byte[])
key = ((byte[])(byte[])key).clone();
}
return res;
}
public static List cloneList(List list)
{
if (list == null)
return null;
List res = new ArrayList(list.size());
for (Iterator it = list.iterator(); it.hasNext(); res.add(clone(it.next())));
return res;
}
public static Object clone(Object obj)
{
if (obj instanceof List)
return cloneList((List)obj);
if (obj instanceof Map)
return cloneMap((Map)obj);
if (obj instanceof byte[])
return ((byte[])(byte[])obj).clone();
else
return obj;
}
public static StringBuffer encodeToXML(Map map, boolean simple)
{
XMLEncoder writer = new XMLEncoder();
return writer.encode(map, simple);
}
private int intToBytes(int i)
{
int charPos = 12;
byte sign = 0;
if (i < 0)
{
sign = 45;
i = -i;
}
while (i >= 0x10000)
{
int q = i / 100;
int r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
int_buffer[--charPos] = DigitOnes[r];
int_buffer[--charPos] = DigitTens[r];
}
do
{
int q = i * 52429 >>> 19;
int r = i - ((q << 3) + (q << 1));
int_buffer[--charPos] = digits[r];
i = q;
} while (i != 0);
if (sign != 0)
int_buffer[--charPos] = sign;
return charPos;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -