File indexing completed on 2025-01-05 04:37:09

0001 /*
0002     SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "bnode.h"
0007 #include <QTextCodec>
0008 #include <util/error.h>
0009 #include <util/log.h>
0010 
0011 namespace bt
0012 {
0013 BNode::BNode(Type type, Uint32 off)
0014     : type(type)
0015     , off(off)
0016     , len(0)
0017 {
0018 }
0019 
0020 BNode::~BNode()
0021 {
0022 }
0023 
0024 ////////////////////////////////////////////////
0025 
0026 BValueNode::BValueNode(const Value &v, Uint32 off)
0027     : BNode(VALUE, off)
0028     , value(v)
0029 {
0030 }
0031 
0032 BValueNode::~BValueNode()
0033 {
0034 }
0035 
0036 void BValueNode::printDebugInfo()
0037 {
0038     if (value.getType() == Value::STRING)
0039         Out(SYS_GEN | LOG_DEBUG) << "Value = " << value.toString() << endl;
0040     else if (value.getType() == Value::INT)
0041         Out(SYS_GEN | LOG_DEBUG) << "Value = " << value.toInt() << endl;
0042     else if (value.getType() == Value::INT64)
0043         Out(SYS_GEN | LOG_DEBUG) << "Value = " << value.toInt64() << endl;
0044 }
0045 
0046 ////////////////////////////////////////////////
0047 
0048 BDictNode::BDictNode(Uint32 off)
0049     : BNode(DICT, off)
0050 {
0051 }
0052 
0053 BDictNode::~BDictNode()
0054 {
0055     QList<DictEntry>::iterator i = children.begin();
0056     while (i != children.end()) {
0057         DictEntry &e = *i;
0058         delete e.node;
0059         ++i;
0060     }
0061 }
0062 
0063 QList<QByteArray> BDictNode::keys() const
0064 {
0065     QList<QByteArray> ret;
0066     ret.reserve(children.size());
0067     QList<DictEntry>::const_iterator i = children.begin();
0068     while (i != children.end()) {
0069         const DictEntry &e = *i;
0070         ret << e.key;
0071         ++i;
0072     }
0073 
0074     return ret;
0075 }
0076 
0077 void BDictNode::insert(const QByteArray &key, BNode *node)
0078 {
0079     DictEntry entry;
0080     entry.key = key;
0081     entry.node = node;
0082     children.append(entry);
0083 }
0084 
0085 BNode *BDictNode::getData(const QByteArray &key)
0086 {
0087     auto i = children.constBegin();
0088     while (i != children.constEnd()) {
0089         const DictEntry &e = *i;
0090         if (e.key == key)
0091             return e.node;
0092         i++;
0093     }
0094     return nullptr;
0095 }
0096 
0097 BDictNode *BDictNode::getDict(const QByteArray &key)
0098 {
0099     QList<DictEntry>::iterator i = children.begin();
0100     while (i != children.end()) {
0101         DictEntry &e = *i;
0102         if (e.key == key)
0103             return dynamic_cast<BDictNode *>(e.node);
0104         ++i;
0105     }
0106     return nullptr;
0107 }
0108 
0109 BListNode *BDictNode::getList(const QByteArray &key)
0110 {
0111     BNode *n = getData(key);
0112     return dynamic_cast<BListNode *>(n);
0113 }
0114 
0115 BValueNode *BDictNode::getValue(const QByteArray &key)
0116 {
0117     BNode *n = getData(key);
0118     return dynamic_cast<BValueNode *>(n);
0119 }
0120 
0121 int BDictNode::getInt(const QByteArray &key)
0122 {
0123     BValueNode *v = getValue(key);
0124     if (!v)
0125         throw bt::Error(QStringLiteral("Key not found in dict"));
0126 
0127     if (v->data().getType() != bt::Value::INT)
0128         throw bt::Error(QStringLiteral("Incompatible type"));
0129 
0130     return v->data().toInt();
0131 }
0132 
0133 qint64 BDictNode::getInt64(const QByteArray &key)
0134 {
0135     BValueNode *v = getValue(key);
0136     if (!v)
0137         throw bt::Error(QStringLiteral("Key not found in dict"));
0138 
0139     if (v->data().getType() != bt::Value::INT64 && v->data().getType() != bt::Value::INT)
0140         throw bt::Error(QStringLiteral("Incompatible type"));
0141 
0142     return v->data().toInt64();
0143 }
0144 
0145 QString BDictNode::getString(const QByteArray &key, QTextCodec *tc)
0146 {
0147     BValueNode *v = getValue(key);
0148     if (!v)
0149         throw bt::Error(QStringLiteral("Key not found in dict"));
0150 
0151     if (v->data().getType() != bt::Value::STRING)
0152         throw bt::Error(QStringLiteral("Incompatible type"));
0153 
0154     if (!tc)
0155         return v->data().toString();
0156     else
0157         return v->data().toString(tc);
0158 }
0159 
0160 QByteArray BDictNode::getByteArray(const QByteArray &key)
0161 {
0162     BValueNode *v = getValue(key);
0163     if (!v)
0164         throw bt::Error(QStringLiteral("Key not found in dict"));
0165 
0166     if (v->data().getType() != bt::Value::STRING)
0167         throw bt::Error(QStringLiteral("Incompatible type"));
0168 
0169     return v->data().toByteArray();
0170 }
0171 
0172 void BDictNode::printDebugInfo()
0173 {
0174     Out(SYS_GEN | LOG_DEBUG) << "DICT" << endl;
0175     QList<DictEntry>::iterator i = children.begin();
0176     while (i != children.end()) {
0177         DictEntry &e = *i;
0178         Out(SYS_GEN | LOG_DEBUG) << QString::fromLatin1(e.key) << ": " << endl;
0179         e.node->printDebugInfo();
0180         ++i;
0181     }
0182     Out(SYS_GEN | LOG_DEBUG) << "END" << endl;
0183 }
0184 
0185 ////////////////////////////////////////////////
0186 
0187 BListNode::BListNode(Uint32 off)
0188     : BNode(LIST, off)
0189 {
0190 }
0191 
0192 BListNode::~BListNode()
0193 {
0194     for (int i = 0; i < children.count(); i++) {
0195         BNode *n = children.at(i);
0196         delete n;
0197     }
0198 }
0199 
0200 void BListNode::append(BNode *node)
0201 {
0202     children.append(node);
0203 }
0204 
0205 BListNode *BListNode::getList(Uint32 idx)
0206 {
0207     return dynamic_cast<BListNode *>(getChild(idx));
0208 }
0209 
0210 BDictNode *BListNode::getDict(Uint32 idx)
0211 {
0212     return dynamic_cast<BDictNode *>(getChild(idx));
0213 }
0214 
0215 BValueNode *BListNode::getValue(Uint32 idx)
0216 {
0217     return dynamic_cast<BValueNode *>(getChild(idx));
0218 }
0219 
0220 int BListNode::getInt(Uint32 idx)
0221 {
0222     BValueNode *v = getValue(idx);
0223     if (!v)
0224         throw bt::Error(QStringLiteral("Key not found in dict"));
0225 
0226     if (v->data().getType() != bt::Value::INT)
0227         throw bt::Error(QStringLiteral("Incompatible type"));
0228 
0229     return v->data().toInt();
0230 }
0231 
0232 qint64 BListNode::getInt64(Uint32 idx)
0233 {
0234     BValueNode *v = getValue(idx);
0235     if (!v)
0236         throw bt::Error(QStringLiteral("Key not found in dict"));
0237 
0238     if (v->data().getType() != bt::Value::INT64 && v->data().getType() != bt::Value::INT)
0239         throw bt::Error(QStringLiteral("Incompatible type"));
0240 
0241     return v->data().toInt64();
0242 }
0243 
0244 QString BListNode::getString(Uint32 idx, QTextCodec *tc)
0245 {
0246     BValueNode *v = getValue(idx);
0247     if (!v)
0248         throw bt::Error(QStringLiteral("Key not found in dict"));
0249 
0250     if (v->data().getType() != bt::Value::STRING)
0251         throw bt::Error(QStringLiteral("Incompatible type"));
0252 
0253     if (!tc)
0254         return v->data().toString();
0255     else
0256         return v->data().toString(tc);
0257 }
0258 
0259 QByteArray BListNode::getByteArray(Uint32 idx)
0260 {
0261     BValueNode *v = getValue(idx);
0262     if (!v)
0263         throw bt::Error(QStringLiteral("Key not found in dict"));
0264 
0265     if (v->data().getType() != bt::Value::STRING)
0266         throw bt::Error(QStringLiteral("Incompatible type"));
0267 
0268     return v->data().toByteArray();
0269 }
0270 
0271 void BListNode::printDebugInfo()
0272 {
0273     Out(SYS_GEN | LOG_DEBUG) << "LIST " << children.count() << endl;
0274     for (int i = 0; i < children.count(); i++) {
0275         BNode *n = children.at(i);
0276         n->printDebugInfo();
0277     }
0278     Out(SYS_GEN | LOG_DEBUG) << "END" << endl;
0279 }
0280 }