| 259 | /// \see MaxLEB128ByteLenFor |
| 260 | template <typename Int> |
| 261 | constexpr int32_t WriteLEB128(Int value, uint8_t* out, int32_t max_out_size) { |
| 262 | constexpr Int kLow7Mask = Int(0x7F); |
| 263 | constexpr Int kHigh7Mask = ~kLow7Mask; |
| 264 | constexpr uint8_t kContinuationBit = 0x80; |
| 265 | |
| 266 | // This encoding does not work for negative values |
| 267 | if constexpr (std::is_signed_v<Int>) { |
| 268 | if (ARROW_PREDICT_FALSE(value < 0)) { |
| 269 | return 0; |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | const auto out_first = out; |
| 274 | |
| 275 | // Write as many bytes as we could be for the given input |
| 276 | while ((value & kHigh7Mask) != Int(0)) { |
| 277 | // We do not have enough room to write the LEB128 |
| 278 | if (ARROW_PREDICT_FALSE(out - out_first >= max_out_size)) { |
| 279 | return 0; |
| 280 | } |
| 281 | |
| 282 | // Write the encoded byte with continuation bit |
| 283 | *out = static_cast<uint8_t>(value & kLow7Mask) | kContinuationBit; |
| 284 | ++out; |
| 285 | // Shift remaining data |
| 286 | value >>= 7; |
| 287 | } |
| 288 | |
| 289 | // We do not have enough room to write the LEB128 |
| 290 | if (ARROW_PREDICT_FALSE(out - out_first >= max_out_size)) { |
| 291 | return 0; |
| 292 | } |
| 293 | |
| 294 | // Write last non-continuing byte |
| 295 | *out = static_cast<uint8_t>(value & kLow7Mask); |
| 296 | ++out; |
| 297 | |
| 298 | return static_cast<int32_t>(out - out_first); |
| 299 | } |
| 300 | |
| 301 | /// Parse a leading LEB128 |
| 302 | /// |