File indexing completed on 2024-06-02 05:05:12

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #ifndef BTBNODE_H
0007 #define BTBNODE_H
0008 
0009 #include "value.h"
0010 #include <QByteArray>
0011 #include <QList>
0012 #include <QVariant>
0013 #include <ktorrent_export.h>
0014 #include <util/constants.h>
0015 
0016 namespace bt
0017 {
0018 class BListNode;
0019 
0020 /**
0021  * @author Joris Guisson
0022  * @brief Base class for a node in a b-encoded piece of data
0023  *
0024  * There are 3 possible pieces of data in b-encoded piece of data.
0025  * This is the base class for all those 3 things.
0026  */
0027 class KTORRENT_EXPORT BNode
0028 {
0029 public:
0030     enum Type {
0031         VALUE,
0032         DICT,
0033         LIST,
0034     };
0035 
0036     /**
0037      * Constructor, sets the Type, and the offset into
0038      * the data.
0039      * @param type Type of node
0040      * @param off The offset into the data
0041      */
0042     BNode(Type type, Uint32 off);
0043     virtual ~BNode();
0044 
0045     /// Get the type of node
0046     Type getType() const
0047     {
0048         return type;
0049     }
0050 
0051     /// Get the offset in the bytearray where this node starts.
0052     Uint32 getOffset() const
0053     {
0054         return off;
0055     }
0056 
0057     /// Get the length this node takes up in the bytearray.
0058     Uint32 getLength() const
0059     {
0060         return len;
0061     }
0062 
0063     /// Set the length
0064     void setLength(Uint32 l)
0065     {
0066         len = l;
0067     }
0068 
0069     /// Print some debugging info
0070     virtual void printDebugInfo() = 0;
0071 
0072 private:
0073     Type type;
0074     Uint32 off, len;
0075 };
0076 
0077 /**
0078  * @author Joris Guisson
0079  * @brief Represents a value (string,bytearray or int) in bencoded data
0080  *
0081  * @todo Use QVariant
0082  */
0083 class KTORRENT_EXPORT BValueNode : public BNode
0084 {
0085     Value value;
0086 
0087 public:
0088     BValueNode(const Value &v, Uint32 off);
0089     ~BValueNode() override;
0090 
0091     const Value &data() const
0092     {
0093         return value;
0094     }
0095     void printDebugInfo() override;
0096 };
0097 
0098 /**
0099  * @author Joris Guisson
0100  * @brief Represents a dictionary in bencoded data
0101  *
0102  */
0103 class KTORRENT_EXPORT BDictNode : public BNode
0104 {
0105     struct DictEntry {
0106         QByteArray key;
0107         BNode *node;
0108     };
0109     QList<DictEntry> children;
0110 
0111 public:
0112     BDictNode(Uint32 off);
0113     ~BDictNode() override;
0114 
0115     /// Get a list of keys
0116     QList<QByteArray> keys() const;
0117 
0118     /**
0119      * Insert a BNode in the dictionary.
0120      * @param key The key
0121      * @param node The node
0122      */
0123     void insert(const QByteArray &key, BNode *node);
0124 
0125     /**
0126      * Get a BNode.
0127      * @param key The key
0128      * @return The node or 0 if there is no node with has key @a key
0129      */
0130     BNode *getData(const QByteArray &key);
0131 
0132     /**
0133      * Get a BListNode.
0134      * @param key The key
0135      * @return The node or 0 if there is no list node with has key @a key
0136      */
0137     BListNode *getList(const QByteArray &key);
0138 
0139     /**
0140      * Get a BDictNode.
0141      * @param key The key
0142      * @return The node or 0 if there is no dict node with has key @a key
0143      */
0144     BDictNode *getDict(const QByteArray &key);
0145 
0146     /**
0147      * Get a BValueNode.
0148      * @param key The key
0149      * @return The node or 0 if there is no value node with has key @a key
0150      */
0151     BValueNode *getValue(const QByteArray &key);
0152 
0153     /// Same as getValue, except directly returns an int, if something goes wrong, an error will be thrown
0154     int getInt(const QByteArray &key);
0155 
0156     /// Same as getValue, except directly returns a qint64, if something goes wrong, an error will be thrown
0157     qint64 getInt64(const QByteArray &key);
0158 
0159     /// Same as getValue, except directly returns a QString, if something goes wrong, an error will be thrown
0160     QString getString(const QByteArray &key, QTextCodec *tc);
0161 
0162     /// Same as getValue, except directly returns an QByteArray, if something goes wrong, an error will be thrown
0163     QByteArray getByteArray(const QByteArray &key);
0164 
0165     void printDebugInfo() override;
0166 };
0167 
0168 /**
0169  * @author Joris Guisson
0170  * @brief Represents a list in bencoded data
0171  *
0172  */
0173 class KTORRENT_EXPORT BListNode : public BNode
0174 {
0175     QList<BNode *> children;
0176 
0177 public:
0178     BListNode(Uint32 off);
0179     ~BListNode() override;
0180 
0181     /**
0182      * Append a node to the list.
0183      * @param node The node
0184      */
0185     void append(BNode *node);
0186     void printDebugInfo() override;
0187 
0188     /// Get the number of nodes in the list.
0189     Uint32 getNumChildren() const
0190     {
0191         return children.count();
0192     }
0193 
0194     /**
0195      * Get a node from the list
0196      * @param idx The index
0197      * @return The node or 0 if idx is out of bounds
0198      */
0199     BNode *getChild(Uint32 idx)
0200     {
0201         return children.at(idx);
0202     }
0203 
0204     /**
0205      * Get a BListNode.
0206      * @param idx The index
0207      * @return The node or 0 if the index is out of bounds or the element
0208      *  at postion @a idx isn't a BListNode.
0209      */
0210     BListNode *getList(Uint32 idx);
0211 
0212     /**
0213      * Get a BDictNode.
0214      * @param idx The index
0215      * @return The node or 0 if the index is out of bounds or the element
0216      *  at postion @a idx isn't a BDictNode.
0217      */
0218     BDictNode *getDict(Uint32 idx);
0219 
0220     /**
0221      * Get a BValueNode.
0222      * @param idx The index
0223      * @return The node or 0 if the index is out of bounds or the element
0224      *  at postion @a idx isn't a BValueNode.
0225      */
0226     BValueNode *getValue(Uint32 idx);
0227 
0228     /// Same as getValue, except directly returns an int, if something goes wrong, an error will be thrown
0229     int getInt(Uint32 idx);
0230 
0231     /// Same as getValue, except directly returns a qint64, if something goes wrong, an error will be thrown
0232     qint64 getInt64(Uint32 idx);
0233 
0234     /// Same as getValue, except directly returns a QString, if something goes wrong, an error will be thrown
0235     QString getString(Uint32 idx, QTextCodec *tc);
0236 
0237     /// Same as getValue, except directly returns an QByteArray, if something goes wrong, an error will be thrown
0238     QByteArray getByteArray(Uint32 idx);
0239 };
0240 }
0241 
0242 #endif