/*
* BeDecoder.java
*
*/
packagecom.vista.test;
importjava.io.*;
importjava.nio.ByteBuffer;
importjava.nio.CharBuffer;
importjava.nio.charset.Charset;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.Iterator;
importjava.util.List;
importjava.util.Map;
/**
* A set of utility methods to decode a bencoded array of byte into a Map.
* integer are represented as Long, String as byte[], dictionnaries as Map, and list as List.
*
*/
publicclassBDecoder
{
//字符集
publicstaticfinalString BYTE_ENCODING ="UTF8";
publicstaticCharset BYTE_CHARSET;
static
{
try
{
BYTE_CHARSET = Charset.forName(BYTE_ENCODING);
}
catch( Throwable e )
{
e.printStackTrace();
}
}
privatestaticfinalbooleanTRACE =true;
privatebooleanrecovery_mode;
publicstaticMap decode(BufferedInputStream is)throwsException
{//解码
return(newBDecoder().decodeStream( is ));
}
publicBDecoder()
{
}
publicMap decodeStream(BufferedInputStream data )throwsException
{
Object res = decodeInputStream(newBDecoderInputStreamStream(data),0);//0指定递归层次从第一层开始
if( res ==null)
{
throw(newException("BDecoder: zero length file"));
}
elseif( !(resinstanceofMap ))
{
throw(newException("BDecoder: top level isn't a Map"));
}
return((Map)res );
}
/**
*
* @param dbis
* @param nesting 递归层次
* @throws Exception
*/
privateObject decodeInputStream(BDecoderInputStream dbis,intnesting )throwsException
{
if(nesting ==0&& !dbis.markSupported())
{
thrownewIOException("InputStream must support the mark() method");
}
//set a mark
dbis.mark(Integer.MAX_VALUE);
//read a byte
inttempByte = dbis.read();//读一个字节
//decide what to do
switch(tempByte)
{
case'd':
{//是字典
//create a new dictionary object
Map tempMap =newHashMap();
try
{
//get the key
byte[] tempByteArray =null;
while((tempByteArray = (byte[]) decodeInputStream(dbis, nesting+1)) !=null)
{
//decode some more
Object value = decodeInputStream(dbis,nesting+1);//读值
// value interning is too CPU-intensive, let's skip that for now
//if(value instanceof byte[] && ((byte[])value).length
//value = StringInterner.internBytes((byte[])value);
// keys often repeat a lot - intern to save space
String