1 /* 2 * This is an open source non-commercial project. Dear PVS-Studio, please check it. 3 * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com 4 * 5 * Copyright (C) 2014-2015 Ivan Romanov <drizt72@zoho.eu> 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22 #pragma once 23 24 #include "abstracttreenode.h" 25 26 #include <QVariant> 27 #include <QMap> 28 #include <QList> 29 30 class Bencode : public AbstractTreeNode<Bencode> 31 { 32 public: 33 enum Type { 34 Invalid, 35 // Not limited, can be signed. I use qlonglong 36 Integer, 37 // It is not correct. By fact can contains byte arrays. 38 // I use QByteArray. When converting to json all non 39 // printable symbols and '%' will be replaced with %HH (hex code) 40 String, 41 List, 42 Dictionary 43 }; 44 45 Bencode(Type type = Type::Invalid, const QByteArray &key = QByteArray()); 46 Bencode(qlonglong integer, const QByteArray &key = QByteArray()); 47 Bencode(const QByteArray &string, const QByteArray &key = QByteArray()); 48 49 void setType(Type type); type()50 inline Type type() const { return _type; } 51 setInteger(qlonglong integer)52 inline void setInteger(qlonglong integer) { _integer = integer; } integer()53 inline qlonglong integer() const { return _integer; } 54 setString(const QByteArray & string)55 inline void setString(const QByteArray &string) { _string = string; } string()56 inline QByteArray string() const { return _string; } 57 setKey(const QByteArray & key)58 inline void setKey(const QByteArray &key) { _key = key; } key()59 inline QByteArray key() const { return _key; } 60 setHex(bool hex)61 inline void setHex(bool hex) { _hex = hex; } hex()62 inline bool hex() const { return _hex; } 63 64 Bencode *checkAndCreate(Type type, int index); 65 Bencode *checkAndCreate(Type type, const QByteArray &key); 66 67 void appendMapItem(Bencode *item); 68 69 // Avoid compilation error due the next not overriden child function child(int index)70 inline Bencode *child(int index) const 71 { 72 return AbstractTreeNode<Bencode>::child(index); 73 } 74 75 Bencode *child(const QByteArray &key) const; 76 isValid()77 inline bool isValid() const { return _type != Invalid; } isInteger()78 inline bool isInteger() const { return _type == Integer; } isString()79 inline bool isString() const { return _type == String; } isList()80 inline bool isList() const { return _type == List; } isDictionary()81 inline bool isDictionary() const { return _type == Dictionary; } 82 83 QByteArray toRaw() const; 84 QVariant toJson() const; 85 86 static Bencode *fromRaw(const QByteArray &raw); 87 static Bencode *fromJson(const QVariant &json); 88 static QString typeToStr(Type type); 89 90 bool compare(const Bencode *other) const; 91 92 // reimplemented 93 Bencode *clone() const override; 94 QString toString() const override; 95 96 private: 97 static Bencode *parseItem(const QByteArray &raw, int &pos); 98 99 static Bencode *parseInteger(const QByteArray &raw, int &pos); 100 static Bencode *parseString(const QByteArray &raw, int &pos); 101 static Bencode *parseList(const QByteArray &raw, int &pos); 102 static Bencode *parseDictionary(const QByteArray &raw, int &pos); 103 104 static QString fromRawString(const QByteArray &raw); 105 static QByteArray toRawString(const QString &string); 106 107 static QByteArray toRaw(const Bencode *bencode); 108 static QVariant toJson(const Bencode *bencode); 109 110 Type _type; 111 112 qlonglong _integer; 113 QByteArray _string; 114 QByteArray _key; 115 bool _hex; 116 }; 117