| 1 | // Copyright (C) 2024 The Qt Company Ltd. |
|---|---|
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
| 3 | |
| 4 | #include <QtProtobuf/private/protobufscalarserializers_p.h> |
| 5 | |
| 6 | QT_BEGIN_NAMESPACE |
| 7 | |
| 8 | QByteArray ProtobufScalarSerializers::serializeVarintCommonImpl(quint64 value) |
| 9 | { |
| 10 | if (value == 0) |
| 11 | return { 1, char(0) }; |
| 12 | |
| 13 | QByteArray result; |
| 14 | while (value != 0) { |
| 15 | // Put 7 bits to result buffer and mark as "not last" (0b10000000) |
| 16 | result.append(c: (value & 0b01111111) | 0b10000000); |
| 17 | // Divide values to chunks of 7 bits and move to next chunk |
| 18 | value >>= 7; |
| 19 | } |
| 20 | |
| 21 | result.back() &= ~0b10000000; |
| 22 | return result; |
| 23 | } |
| 24 | |
| 25 | /* |
| 26 | Gets length of a byte-array and prepends to it its serialized length value |
| 27 | using the appropriate serialization algorithm |
| 28 | |
| 29 | Returns 'data' with its length prepended |
| 30 | */ |
| 31 | QByteArray ProtobufScalarSerializers::prependLengthDelimitedSize(const QByteArray &data) |
| 32 | { |
| 33 | return serializeVarintCommonImpl(value: data.size()) + data; |
| 34 | } |
| 35 | |
| 36 | std::optional<QByteArray> |
| 37 | ProtobufScalarSerializers::deserializeLengthDelimited(QProtobufSelfcheckIterator &it) |
| 38 | { |
| 39 | if (it.bytesLeft() != 0) { |
| 40 | if (auto opt = deserializeVarintCommon<QtProtobuf::uint64>(it); opt) { |
| 41 | if (quint64 length = opt.value(); it.isValid() && quint64(it.bytesLeft()) >= length |
| 42 | && length <= quint64(QByteArray::maxSize())) { |
| 43 | QByteArray result(it.data(), qsizetype(length)); |
| 44 | it += length; |
| 45 | return { std::move(result) }; |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | return std::nullopt; |
| 50 | } |
| 51 | |
| 52 | QT_END_NAMESPACE |
| 53 |
