| 295 | /// \see MaxLEB128ByteLenFor |
| 296 | template <typename Int> |
| 297 | constexpr int32_t WriteLEB128(Int value, uint8_t* out, int32_t max_out_size) { |
| 298 | constexpr Int kLow7Mask = Int(0x7F); |
| 299 | constexpr Int kHigh7Mask = ~kLow7Mask; |
| 300 | constexpr uint8_t kContinuationBit = 0x80; |
| 301 | |
| 302 | // This encoding does not work for negative values |
| 303 | if constexpr (std::is_signed_v<Int>) { |
| 304 | if (ARROW_PREDICT_FALSE(value < 0)) { |
| 305 | return 0; |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | const auto out_first = out; |
| 310 | |
| 311 | // Write as many bytes as we could be for the given input |
| 312 | while ((value & kHigh7Mask) != Int(0)) { |
| 313 | // We do not have enough room to write the LEB128 |
| 314 | if (ARROW_PREDICT_FALSE(out - out_first >= max_out_size)) { |
| 315 | return 0; |
| 316 | } |
| 317 | |
| 318 | // Write the encoded byte with continuation bit |
| 319 | *out = static_cast<uint8_t>(value & kLow7Mask) | kContinuationBit; |
| 320 | ++out; |
| 321 | // Shift remaining data |
| 322 | value >>= 7; |
| 323 | } |
| 324 | |
| 325 | // We do not have enough room to write the LEB128 |
| 326 | if (ARROW_PREDICT_FALSE(out - out_first >= max_out_size)) { |
| 327 | return 0; |
| 328 | } |
| 329 | |
| 330 | // Write last non-continuing byte |
| 331 | *out = static_cast<uint8_t>(value & kLow7Mask); |
| 332 | ++out; |
| 333 | |
| 334 | return static_cast<int32_t>(out - out_first); |
| 335 | } |
| 336 | |
| 337 | /// Parse a leading LEB128 |
| 338 | /// |