| 59 | //===----------------------------------------------------------------------===// |
| 60 | namespace { |
| 61 | class EncodingWriter { |
| 62 | public: |
| 63 | EncodingWriter(raw_ostream &stream, uint64_t alignment = 1) |
| 64 | : stream(stream), requiredAlignment(alignment) {} |
| 65 | |
| 66 | void writeByte(uint8_t byte) { stream.write(static_cast<char>(byte)); } |
| 67 | |
| 68 | template <typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0> |
| 69 | void writeByte(Enum value) { |
| 70 | writeByte(static_cast<uint8_t>(value)); |
| 71 | } |
| 72 | |
| 73 | void writeVarInt(uint64_t value) { |
| 74 | uint8_t bytes[10]; // Supports up to 64 bits |
| 75 | size_t index = 0; |
| 76 | |
| 77 | do { |
| 78 | uint8_t byte = value & 0x7F; // Lower 7 bits |
| 79 | value >>= 7; |
| 80 | if (value != 0) |
| 81 | byte |= 0x80; // Set continuation bit |
| 82 | bytes[index++] = byte; |
| 83 | } while (value != 0 && index < sizeof(bytes)); |
| 84 | |
| 85 | stream.write(reinterpret_cast<char *>(bytes), index); |
| 86 | } |
| 87 | |
| 88 | template <typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0> |
| 89 | void writeVarInt(Enum value) { |
| 90 | writeVarInt(static_cast<uint64_t>(value)); |
| 91 | } |
| 92 | |
| 93 | /// Emit a signed variable length integer. Signed varints are encoded using |
| 94 | /// a varint with zigzag encoding, meaning that we use the low bit of the |
| 95 | /// value to indicate the sign of the value. This allows for more efficient |
| 96 | /// encoding of negative values by limiting the number of active bits |
| 97 | void writeSignedVarInt(uint64_t value) { |
| 98 | writeVarInt((value << 1) ^ (uint64_t)((int64_t)value >> 63)); |
| 99 | } |
| 100 | |
| 101 | template <typename T> |
| 102 | std::enable_if_t<std::is_integral<T>::value, void> writeLE(T value) { |
| 103 | for (size_t i = 0; i < sizeof(T); ++i) { |
| 104 | writeByte(value & 0xFF); |
| 105 | // Only shift if there are more bytes to process |
| 106 | if (sizeof(T) > 1 && i < sizeof(T) - 1) |
| 107 | value >>= 8; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | template <typename T> |
| 112 | void writeLE(ArrayRef<T> values) { |
| 113 | for (T value : values) |
| 114 | writeLE<T>(value); |
| 115 | } |
| 116 | |
| 117 | template <typename T> |
| 118 | void writeLEVarSize(ArrayRef<T> values) { |
nothing calls this directly
no outgoing calls
no test coverage detected