Add collection decoding

This commit is contained in:
Anton Thomasson 2020-06-13 10:42:07 +02:00
parent 761f0a3869
commit 035e310069
2 changed files with 106 additions and 14 deletions

View file

@ -143,7 +143,7 @@ QJsonValue IppMsg::consume_value(quint8 tag, Bytestream& data)
break; break;
} }
}; };
return value; return QJsonObject {{"tag", tag}, {"value", value}};
} }
QJsonArray IppMsg::get_unnamed_attributes(Bytestream& data) QJsonArray IppMsg::get_unnamed_attributes(Bytestream& data)
@ -166,12 +166,92 @@ QJsonArray IppMsg::get_unnamed_attributes(Bytestream& data)
return attrs; return attrs;
} }
QJsonArray untag_values(QJsonArray taggedValues)
{
QJsonArray res;
foreach(QJsonValue it, taggedValues)
{
res.append(it.toObject()["value"]);
}
return res;
}
QJsonValue IppMsg::collect_attributes(QJsonArray& attrs)
{
QJsonArray resArr;
QJsonObject resObj = QJsonObject();
while(!attrs.empty())
{
QJsonObject tmpobj = attrs.takeAt(0).toObject();
quint8 tag = tmpobj["tag"].toInt();
if(tag == MemberName)
{
QString key = tmpobj["value"].toString();
tmpobj = attrs.takeAt(0).toObject();
if(tmpobj["tag"] == BeginCollection)
{
resObj[key] = collect_attributes(attrs);
}
else
{ // This should be general data attributes
QJsonArray restOfSet;
while(attrs.begin()->toObject()["tag"] == tmpobj["tag"])
{
restOfSet.append(attrs.takeAt(0));
}
if(restOfSet.empty())
{
resObj[key] = tmpobj;
}
else
{
restOfSet.prepend(tmpobj);
tmpobj["value"] = untag_values(restOfSet);
resObj[key] = tmpobj;
}
}
}
else if(tag == EndCollection)
{
resArr.append(resObj);
resObj = QJsonObject();
if(attrs.empty())
{ // end of collection
break;
}
else if(attrs.begin()->toObject()["tag"] == BeginCollection)
{ // this is a 1setOf
continue;
}
else
{ // the following attribute(s) belong to an outer collection
break;
}
}
else
{
qDebug() << "out of sync with collection" << tmpobj;
Q_ASSERT("NOOOOO!");
}
}
if(resArr.size()==1)
{ // The code above unconditionally produces arrays, collapse if they are just a single object
return resArr.first();
}
else
{
return resArr;
}
}
QString IppMsg::consume_attribute(QJsonObject& attrs, Bytestream& data) QString IppMsg::consume_attribute(QJsonObject& attrs, Bytestream& data)
{ {
quint8 tag; quint8 tag;
quint16 tmp_len; quint16 tmp_len;
QString name; QString name;
QJsonValue value; QJsonValue taggedValue;
std::string tmp_str = ""; std::string tmp_str = "";
data >> tag >> tmp_len; data >> tag >> tmp_len;
@ -180,25 +260,33 @@ QString IppMsg::consume_attribute(QJsonObject& attrs, Bytestream& data)
QString name0 = tmp_str.c_str(); QString name0 = tmp_str.c_str();
name = tmp_str.c_str(); name = tmp_str.c_str();
value = consume_value(tag, data); taggedValue = consume_value(tag, data);
QJsonArray unnamed = get_unnamed_attributes(data); QJsonArray unnamed = get_unnamed_attributes(data);
qDebug() << name0 << tag << tmp_len << value << unnamed; // qDebug() << name0 << tag << tmp_len << value << unnamed;
if(!unnamed.empty()) if(tag == BeginCollection)
{ {
unnamed.prepend(value); qDebug() << "Unnamed attrs for collection" << unnamed;
attrs.insert(name, QJsonObject {{"tag", tag}, {"value", unnamed}});
QJsonValue collected = collect_attributes(unnamed);
qDebug() << "collected" << collected;
taggedValue = QJsonObject {{"tag", tag}, {"value", collected}};
}
bool noList = (tag == Boolean || tag == IntegerRange);
bool forceArray = ((name.endsWith("-supported") || name == "printer-icons") && !noList);
if(!unnamed.empty() || forceArray)
{
unnamed.prepend(taggedValue);
attrs.insert(name, QJsonObject {{"tag", tag}, {"value", untag_values(unnamed)}});
} }
else else
{ {
bool noList = value.isObject() || value.isBool(); attrs.insert(name, taggedValue);
if((name.endsWith("-supported") || name == "printer-icons") && !noList)
{
value = QJsonArray {value};
}
attrs.insert(name, QJsonObject {{"tag", tag}, {"value", value}});
} }
return name; return name;
} }

View file

@ -30,8 +30,10 @@ public:
DateTime = 0x31, DateTime = 0x31,
Resolution = 0x32, Resolution = 0x32,
IntegerRange = 0x33, IntegerRange = 0x33,
BeginCollection = 0x34,
TextWithLanguage = 0x35, TextWithLanguage = 0x35,
NameWithLanguage = 0x36, NameWithLanguage = 0x36,
EndCollection = 0x37,
TextWithoutLanguage = 0x41, TextWithoutLanguage = 0x41,
NameWithoutLanguage = 0x42, NameWithoutLanguage = 0x42,
Keyword = 0x44, Keyword = 0x44,
@ -39,7 +41,8 @@ public:
UriScheme = 0x46, UriScheme = 0x46,
Charset = 0x47, Charset = 0x47,
NaturalLanguage = 0x48, NaturalLanguage = 0x48,
MimeMediaType = 0x49 MimeMediaType = 0x49,
MemberName = 0x4A
}; };
Q_ENUMS(IppTag) Q_ENUMS(IppTag)
@ -80,6 +83,7 @@ protected:
private: private:
QJsonValue consume_value(quint8 tag, Bytestream& data); QJsonValue consume_value(quint8 tag, Bytestream& data);
QJsonArray get_unnamed_attributes(Bytestream& data); QJsonArray get_unnamed_attributes(Bytestream& data);
QJsonValue collect_attributes(QJsonArray& attrs);
QString consume_attribute(QJsonObject& attrs, Bytestream& data); QString consume_attribute(QJsonObject& attrs, Bytestream& data);
Bytestream encode_attr(quint8 tag, QString name, QJsonValueRef value); Bytestream encode_attr(quint8 tag, QString name, QJsonValueRef value);