File indexing completed on 2025-06-29 04:47:08
0001 /* 0002 SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #ifndef KITINERARY_PROTOBUFSTREAMREADER_H 0007 #define KITINERARY_PROTOBUFSTREAMREADER_H 0008 0009 #include <QByteArray> 0010 #include <QMetaType> 0011 0012 #include <string_view> 0013 0014 class QString; 0015 0016 namespace KItinerary { 0017 0018 /** Protocol Buffers stream reader. 0019 * For use on protobuf data for which the full format definition is unknown. 0020 * @see https://protobuf.dev/ 0021 */ 0022 class ProtobufStreamReader 0023 { 0024 Q_GADGET 0025 public: 0026 explicit ProtobufStreamReader(); 0027 explicit ProtobufStreamReader(std::string_view data); 0028 explicit ProtobufStreamReader(const QByteArray &data); 0029 ~ProtobufStreamReader(); 0030 0031 /** Returns the number of the current field. 0032 * Assumes the cursor is on the beginning of a field. The cursor does not advance. 0033 */ 0034 Q_INVOKABLE quint64 fieldNumber(); 0035 0036 enum WireType { 0037 VARINT, 0038 I64, 0039 LEN, 0040 SGROUP, 0041 EGROUP, 0042 I32, 0043 }; 0044 Q_ENUM(WireType) 0045 0046 /** Returns the wire type of the current field. 0047 * Assumes the cursor is on the beginning of a field. The cursor does not advance. 0048 */ 0049 Q_INVOKABLE WireType wireType(); 0050 0051 /** Read a field of type VARINT. 0052 * This assumes the cursor is placed at the beginning of a field with wire type VARINT. 0053 * The cursor is advanced to after the field. 0054 */ 0055 Q_INVOKABLE quint64 readVarintField(); 0056 0057 /** Reads a field of type LEN. 0058 * This assumes the cursor is placed at the beginning of a field with wire type LEN. 0059 * The cursor is advanced to after the field. 0060 */ 0061 std::string_view readLengthDelimitedRecord(); 0062 0063 /** Reads a string. 0064 * This assumes the cursor is placed at the beginning of a field with wire type LEN 0065 * containing a string. The cursor is advanced to after the field. 0066 */ 0067 Q_INVOKABLE QString readString(); 0068 0069 /** Reads a nested message. 0070 * This assumes the cursor is placed at the beginning of a field with wire type LEN 0071 * containing a sub-message. The cursor is advanced to after the field. 0072 */ 0073 Q_INVOKABLE KItinerary::ProtobufStreamReader readSubMessage(); 0074 0075 /** Returns @c true when having reached the end of the stream. */ 0076 Q_INVOKABLE bool atEnd() const; 0077 0078 /** Skips over the next field in the stream. */ 0079 Q_INVOKABLE void skip(); 0080 0081 ///@cond internal 0082 /** Read Base 128 varint value from the current stream position and advances the cursor. */ 0083 uint64_t readVarint(); 0084 /** Read Base 128 varint value from the current stream position without advancing the cursor. */ 0085 uint64_t peekVarint(); 0086 ///@endcond 0087 0088 private: 0089 QByteArray m_ownedData; 0090 std::string_view m_data; 0091 std::string_view::size_type m_cursor = 0; 0092 }; 0093 0094 } 0095 0096 #endif // KITINERARY_PROTOBUFSTREAMREADER_H