QVariant Message::parseValue(QIODevice &data, const quint8 wireType, const Types::ScalarType scalarType, const QString &tagPath) const { // A small sanity check. In this case, the wireType will take precedence. if ((scalarType != Types::Unknown) && (wireType != Types::LengthDelimeted) && (wireType != Types::getWireType(scalarType))) { qWarning() << tagPath << "wire type" << wireType << "does not match " "expected wire type" << Types::getWireType(scalarType) << "for " "scalar type" << scalarType; } switch (wireType) { case Types::Varint: // int32, int64, uint32, uint64, sint32, sint64, bool, enum. switch (scalarType) { case Types::Int32: return parseStandardVarint(data); case Types::Int64: return parseStandardVarint(data); case Types::Uint32: return parseUnsignedVarint(data); case Types::Uint64: return parseUnsignedVarint(data); case Types::Sint32: return parseSignedVarint(data); case Types::Sint64: return parseSignedVarint(data); case Types::Bool: return parseStandardVarint(data); case Types::Enumerator: return parseStandardVarint(data); default: return parseStandardVarint(data); } break; case Types::SixtyFourBit: // fixed64, sfixed64, double. switch (scalarType) { case Types::Fixed64: return parseFixedNumber<quint64>(data); case Types::Sfixed64: return parseFixedNumber<qint64>(data); case Types::Double: return parseFixedNumber<double>(data); default: return data.read(8); // The raw 8-byte sequence. } break; case Types::LengthDelimeted: // string, bytes, embedded messages, packed repeated fields. return parseLengthDelimitedValue(data, scalarType, tagPath); case Types::StartGroup: // deprecated. return parse(data, tagPath + pathSeparator); case Types::EndGroup: // deprecated. return QVariant(); // Caller will need to end the group started previously. case Types::ThirtyTwoBit: // fixed32, sfixed32, float. switch (scalarType) { case Types::Fixed32: return parseFixedNumber<quint32>(data); case Types::Sfixed32: return parseFixedNumber<qint32>(data); case Types::Float: return parseFixedNumber<float>(data); default: return data.read(4); // The raw 4-byte sequence. } break; } qWarning() << "invalid wireType:" << wireType << "(tagPath:" << tagPath << ')'; return QVariant(); }
QVariantList parseStandardVarints(QIODevice &data, int maxItems) { QVariantList list; for (; (maxItems < 0) || (list.size() < maxItems);) { const QVariant item = parseStandardVarint(data); if (item.isValid()) { list << item; } else { maxItems = 0; } } return list; }
QVariant parseStandardVarint(QByteArray data) { QBuffer buffer(&data); buffer.open(QIODevice::ReadOnly); return parseStandardVarint(buffer); }