• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdenetwork
  • Sitemap
  • Contact Us
 

kget

bdecoder.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Joris Guisson                                   *
00003  *   joris.guisson@gmail.com                                               *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.             *
00019  ***************************************************************************/
00020 #include "bdecoder.h"
00021 #include <util/log.h>
00022 #include <util/error.h>
00023 #include <klocale.h>
00024 #include "bnode.h"
00025 
00026 namespace bt
00027 {
00028 
00029     BDecoder::BDecoder(const QByteArray & data,bool verbose,Uint32 off)
00030     : data(data),pos(off),verbose(verbose)
00031     {
00032     }
00033 
00034 
00035     BDecoder::~BDecoder()
00036     {}
00037 
00038     BNode* BDecoder::decode()
00039     {
00040         if (pos >= (Uint32)data.size())
00041             return 0;
00042 
00043         if (data[pos] == 'd')
00044         {
00045             return parseDict();
00046         }
00047         else if (data[pos] == 'l')
00048         {
00049             return parseList();
00050         }
00051         else if (data[pos] == 'i')
00052         {
00053             return parseInt();
00054         }
00055         else if (data[pos] >= '0' && data[pos] <= '9')
00056         {
00057             return parseString();
00058         }
00059         else
00060         {
00061             throw Error(i18n("Illegal token: %1",data[pos]));
00062         }
00063     }
00064 
00065     BDictNode* BDecoder::parseDict()
00066     {
00067         Uint32 off = pos;
00068         // we're now entering a dictionary
00069         BDictNode* curr = new BDictNode(off);
00070         pos++;
00071         if (verbose) Out(SYS_GEN|LOG_DEBUG) << "DICT" << endl;
00072         try
00073         {
00074             while (pos < (Uint32)data.size() && data[pos] != 'e')
00075             {
00076                 if (verbose) Out(SYS_GEN|LOG_DEBUG) << "Key : " << endl;
00077                 BNode* kn = decode(); 
00078                 BValueNode* k = dynamic_cast<BValueNode*>(kn);
00079                 if (!k || k->data().getType() != Value::STRING)
00080                 {
00081                     delete kn;
00082                     throw Error(i18n("Decode error"));
00083                 }
00084 
00085                 QByteArray key = k->data().toByteArray();
00086                 delete kn;
00087                 
00088                 BNode* data = decode();
00089                 curr->insert(key,data);
00090             }
00091             pos++;
00092         }
00093         catch (...)
00094         {
00095             delete curr;
00096             throw;
00097         }
00098         if (verbose) Out(SYS_GEN|LOG_DEBUG) << "END" << endl;
00099         curr->setLength(pos - off);
00100         return curr;
00101     }
00102 
00103     BListNode* BDecoder::parseList()
00104     {
00105         Uint32 off = pos;
00106         if (verbose) Out(SYS_GEN|LOG_DEBUG) << "LIST" << endl;
00107         BListNode* curr = new BListNode(off);
00108         pos++;
00109         try
00110         {
00111             while (pos < (Uint32)data.size() && data[pos] != 'e')
00112             {
00113                 BNode* n = decode();
00114                 curr->append(n);
00115             }
00116             pos++;
00117         }
00118         catch (...)
00119         {
00120             delete curr;
00121             throw;
00122         }
00123         if (verbose) Out(SYS_GEN|LOG_DEBUG) << "END" << endl;
00124         curr->setLength(pos - off);
00125         return curr;
00126     }
00127 
00128     BValueNode* BDecoder::parseInt()
00129     {
00130         Uint32 off = pos;
00131         pos++;
00132         QString n;
00133         // look for e and add everything between i and e to n
00134         while (pos < (Uint32)data.size() && data[pos] != 'e')
00135         {
00136             n += data[pos];
00137             pos++;
00138         }
00139 
00140         // check if we aren't at the end of the data
00141         if (pos >= (Uint32)data.size())
00142         {
00143             throw Error(i18n("Unexpected end of input"));
00144         }
00145 
00146         // try to decode the int
00147         bool ok = true;
00148         int val = 0;
00149         val = n.toInt(&ok);
00150         if (ok)
00151         {
00152             pos++;
00153             if (verbose) Out(SYS_GEN|LOG_DEBUG) << "INT = " << val << endl;
00154             BValueNode* vn = new BValueNode(Value(val),off);
00155             vn->setLength(pos - off);
00156             return vn;
00157         }
00158         else
00159         {
00160             Int64 bi = 0LL;
00161             bi = n.toLongLong(&ok);
00162             if (!ok)
00163                 throw Error(i18n("Cannot convert %1 to an int",n));
00164 
00165             pos++;
00166             if (verbose) Out(SYS_GEN|LOG_DEBUG) << "INT64 = " << n << endl;
00167             BValueNode* vn = new BValueNode(Value(bi),off);
00168             vn->setLength(pos - off);
00169             return vn;
00170         }
00171     }
00172 
00173     BValueNode* BDecoder::parseString()
00174     {
00175         Uint32 off = pos;
00176         // string are encoded 4:spam (length:string)
00177 
00178         // first get length by looking for the :
00179         QString n;
00180         while (pos < (Uint32)data.size() && data[pos] != ':')
00181         {
00182             n += data[pos];
00183             pos++;
00184         }
00185         // check if we aren't at the end of the data
00186         if (pos >= (Uint32)data.size())
00187         {
00188             throw Error(i18n("Unexpected end of input"));
00189         }
00190 
00191         // try to decode length
00192         bool ok = true;
00193         int len = 0;
00194         len = n.toInt(&ok);
00195         if (!ok)
00196         {
00197             throw Error(i18n("Cannot convert %1 to an int",n));
00198         }
00199         // move pos to the first part of the string
00200         pos++;
00201         if (pos + len > (Uint32)data.size())
00202             throw Error(i18n("Torrent is incomplete!"));
00203             
00204         QByteArray arr(data.constData() + pos,len);
00205         pos += len;
00206         // read the string into n
00207 
00208         // pos should be positioned right after the string
00209         BValueNode* vn = new BValueNode(Value(arr),off);
00210         vn->setLength(pos - off);
00211         if (verbose)
00212         {
00213             if (arr.size() < 200)
00214                 Out(SYS_GEN|LOG_DEBUG) << "STRING " << QString(arr) << endl;
00215             else
00216                 Out(SYS_GEN|LOG_DEBUG) << "STRING " << "really long string" << endl;
00217         }
00218         return vn;
00219     }
00220 }
00221 

kget

Skip menu "kget"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdenetwork

Skip menu "kdenetwork"
  • kget
  • kopete
  •   kopete
  •   libkopete
  •       libpapillon
  • krfb
Generated for kdenetwork by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal