| 87 | //===----------------------------------------------------------------------===// |
| 88 | namespace { |
| 89 | class EncodingReader { |
| 90 | public: |
| 91 | EncodingReader(ArrayRef<uint8_t> data, MLIRContext &context) |
| 92 | : data(data), offset(0), context(context) {} |
| 93 | |
| 94 | LogicalResult readVarInt(uint64_t &result, uint64_t max = 0) { |
| 95 | if (offset >= data.size()) |
| 96 | return failure(); |
| 97 | result = 0; |
| 98 | uint64_t shift = 0; |
| 99 | uint8_t byte; |
| 100 | do { |
| 101 | if (offset >= data.size() || shift > 63) |
| 102 | return failure(); |
| 103 | byte = data[offset++]; |
| 104 | uint64_t value = byte & 0x7F; |
| 105 | result |= (value << shift); |
| 106 | shift += 7; |
| 107 | } while (byte & 0x80); |
| 108 | if (max && result > max) |
| 109 | return emitError() << "varint value exceeds maximum supported" |
| 110 | << " capacity. (expected value less than " << max |
| 111 | << ", got " << result << ")."; |
| 112 | return success(); |
| 113 | } |
| 114 | |
| 115 | /// Parse a signed variable length encoded integer from the byte stream. A |
| 116 | /// signed varint is encoded as a normal varint with zigzag encoding applied, |
| 117 | /// i.e. the low bit of the value is used to indicate the sign. |
| 118 | LogicalResult readSignedVarInt(uint64_t &result) { |
| 119 | if (failed(readVarInt(result))) |
| 120 | return failure(); |
| 121 | // Essentially (but using unsigned): (x >> 1) ^ -(x & 1). |
| 122 | result = (result >> 1) ^ (~(result & 1) + 1); |
| 123 | return success(); |
| 124 | } |
| 125 | |
| 126 | template <typename T> |
| 127 | std::enable_if_t<std::is_integral<T>::value, LogicalResult> readLE(T &value) { |
| 128 | if (offset + sizeof(T) > data.size()) |
| 129 | return failure(); |
| 130 | value = 0; |
| 131 | for (size_t i = 0; i < sizeof(T); ++i) |
| 132 | value |= static_cast<T>(data[offset++]) << (8 * i); |
| 133 | return success(); |
| 134 | } |
| 135 | |
| 136 | template <typename T> |
| 137 | std::enable_if_t<std::is_integral<T>::value, T> readLE() { |
| 138 | T value = 0; |
| 139 | if (failed(readLE(value))) |
| 140 | return 0; |
| 141 | return value; |
| 142 | } |
| 143 | |
| 144 | template <typename T> |
| 145 | std::enable_if_t<std::is_integral<T>::value, LogicalResult> |
| 146 | readLE(size_t count, SmallVectorImpl<T> &result) { |
nothing calls this directly
no outgoing calls
no test coverage detected