JScript: Converting a torrent file to a JScript dictionary

From Theory.org Wiki
Jump to: navigation, search

Function parseTorrentFile() takes a path to a torrent file, converts that torrent file to a JScript dictionary, and returns that dictionary. Bencoded strings and integers are converted to JScript strings and numbers, respectively. Bencoded lists become JScript arrays, bencoded dictionaries are converted to JScript dictionaries.

/* Written by Sergej Benilov <sergej dot benilov at googlemail dot com> */


function parseTorrentFile(filename)

{
  
var ForReading = 1;
var fso_in, infile;

var cont_pos = 0;
var ch;

var Stack = new Array();
var StackOfKeys = new Array();
var DictKeyExpectedFlag = false;

var MainDict;
var tmp;

var StrLength = new RegExp("(\\d*?):","gim");
var Int = new RegExp("i(\\d*?)e","gim");


/* open torrent file as ASCII */
fso_in = new ActiveXObject("Scripting.FileSystemObject");
infile = fso_in.OpenTextFile(filename, ForReading, false, 0);

/* read in contents of torrent file */
var contents  = new String(infile.ReadAll());

do 
{


 ch = contents.charAt(cont_pos);
 switch (ch)
            {
              case 'd':
                  DictKeyExpectedFlag = true;
                  tmp = new ActiveXObject("Scripting.Dictionary");
                  if (MainDict == undefined) {MainDict = tmp;}
                  Stack.push(tmp);
                  cont_pos++;
                  break;
              
              case 'l':
                  Stack.push(new Array());
                  cont_pos++;
                  break;
                
              case 'e':
                  tmp = Stack.pop();
                  if (Stack.length > 0) 
                  
                  {
                    if (Stack[Stack.length-1].constructor == Array) {
                      /* if there is a list on the top of stack, add popped element to it */
                      Stack[Stack.length-1].push(tmp);                                        
                    } else {
                      /* there is a dictionary on the top of stack, add popped element to it */
                      Stack[Stack.length-1].Item(StackOfKeys.pop()) = tmp;
                      DictKeyExpectedFlag = true;
                    }
                    
                  }
                                    
                  cont_pos++;
                  break;
                
              case 'i':                   
                  /* read in number */
                  Int.lastIndex = cont_pos;
                  Int.exec(contents);
                  
                  /* add number to list */
                  if (Stack[Stack.length-1].constructor == Array)
                  {
                    Stack[Stack.length-1].push(parseInt(RegExp.$1));
                  }
                  
                  /* add number to dictionary */
                  else
                    {
                  Stack[Stack.length-1].Item(StackOfKeys.pop()) = parseInt(RegExp.$1);
                  DictKeyExpectedFlag = true;
                    }
                  cont_pos = contents.indexOf("e",cont_pos) + 1;
                  break;
                
              default:                
                /* read in string */
                StrLength.lastIndex = cont_pos;
                StrLength.exec(contents);
                tmp = contents.substr(contents.indexOf(":",cont_pos)+1,RegExp.$1);                
                
                /* add string to list */
                if (Stack[Stack.length-1].constructor == Array)
                  {
                    Stack[Stack.length-1].push(tmp);
                  }
                
                /* add string to dictionary */
                else
                    {
                  if (DictKeyExpectedFlag) {Stack[Stack.length-1].Add(tmp,"");
                  	DictKeyExpectedFlag = false;
                  	StackOfKeys.push(tmp); }
                  else {Stack[Stack.length-1].Item(StackOfKeys.pop()) = tmp;
                  	DictKeyExpectedFlag = true;}
                    }
                
                cont_pos = contents.indexOf(":",cont_pos) + 1 + parseInt(RegExp.$1);
              }
              
            


}

while (Stack.length > 0);


infile.close();

return MainDict;

}

To retrieve information from a torrent file, you would import parseTorrentFile() in your own script and do something like this:

var Torrent = parseTorrentFile("foo.torrent");

/* get the announce URL of the tracker */
var Announce = Torrent("announce");

/* get the creation time of the torrent */
var Creation_Time = new Date(Torrent("creation date")*1000);
Creation_Time = Creation_Time.toUTCString();

/* get the number of files of the torrent (assuming a multi-file torrent) */
var Number_of_Files = Torrent("info")("files").length;

/* get the size of the first file of the torrent (assuming a multi-file torrent) */
var Length_of_First_File = Torrent("info")("files")[0]("length");