| //===-- sanitizer_leb128.h --------------------------------------*- C++ -*-===// | 
 | // | 
 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
 | // See https://llvm.org/LICENSE.txt for license information. | 
 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #ifndef SANITIZER_LEB128_H | 
 | #define SANITIZER_LEB128_H | 
 |  | 
 | #include "sanitizer_common.h" | 
 | #include "sanitizer_internal_defs.h" | 
 |  | 
 | namespace __sanitizer { | 
 |  | 
 | template <typename T, typename It> | 
 | It EncodeSLEB128(T value, It begin, It end) { | 
 |   bool more; | 
 |   do { | 
 |     u8 byte = value & 0x7f; | 
 |     // NOTE: this assumes that this signed shift is an arithmetic right shift. | 
 |     value >>= 7; | 
 |     more = !((((value == 0) && ((byte & 0x40) == 0)) || | 
 |               ((value == -1) && ((byte & 0x40) != 0)))); | 
 |     if (more) | 
 |       byte |= 0x80; | 
 |     if (UNLIKELY(begin == end)) | 
 |       break; | 
 |     *(begin++) = byte; | 
 |   } while (more); | 
 |   return begin; | 
 | } | 
 |  | 
 | template <typename T, typename It> | 
 | It DecodeSLEB128(It begin, It end, T* v) { | 
 |   T value = 0; | 
 |   unsigned shift = 0; | 
 |   u8 byte; | 
 |   do { | 
 |     if (UNLIKELY(begin == end)) | 
 |       return begin; | 
 |     byte = *(begin++); | 
 |     T slice = byte & 0x7f; | 
 |     value |= slice << shift; | 
 |     shift += 7; | 
 |   } while (byte >= 128); | 
 |   if (shift < 64 && (byte & 0x40)) | 
 |     value |= (-1ULL) << shift; | 
 |   *v = value; | 
 |   return begin; | 
 | } | 
 |  | 
 | template <typename T, typename It> | 
 | It EncodeULEB128(T value, It begin, It end) { | 
 |   do { | 
 |     u8 byte = value & 0x7f; | 
 |     value >>= 7; | 
 |     if (value) | 
 |       byte |= 0x80; | 
 |     if (UNLIKELY(begin == end)) | 
 |       break; | 
 |     *(begin++) = byte; | 
 |   } while (value); | 
 |   return begin; | 
 | } | 
 |  | 
 | template <typename T, typename It> | 
 | It DecodeULEB128(It begin, It end, T* v) { | 
 |   T value = 0; | 
 |   unsigned shift = 0; | 
 |   u8 byte; | 
 |   do { | 
 |     if (UNLIKELY(begin == end)) | 
 |       return begin; | 
 |     byte = *(begin++); | 
 |     T slice = byte & 0x7f; | 
 |     value += slice << shift; | 
 |     shift += 7; | 
 |   } while (byte >= 128); | 
 |   *v = value; | 
 |   return begin; | 
 | } | 
 |  | 
 | }  // namespace __sanitizer | 
 |  | 
 | #endif  // SANITIZER_LEB128_H |