1 //===- LEB128.h -----------------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef MCLD_SUPPORT_LEB128_H_ 10 #define MCLD_SUPPORT_LEB128_H_ 11 12 #include <stdint.h> 13 #include <sys/types.h> 14 15 namespace mcld { 16 17 namespace leb128 { 18 19 typedef unsigned char ByteType; 20 21 /* Forward declarations */ 22 template <typename IntType> 23 size_t encode(ByteType*& pBuf, IntType pValue); 24 25 template <typename IntType> 26 IntType decode(const ByteType* pBuf, size_t& pSize); 27 28 template <typename IntType> 29 IntType decode(const ByteType*& pBuf); 30 31 /* 32 * Given an integer, this function returns the number of bytes required to 33 * encode it in ULEB128 format. 34 */ 35 template <typename IntType> 36 size_t size(IntType pValue) { 37 size_t size = 1; 38 while (pValue > 0x80) { 39 pValue >>= 7; 40 ++size; 41 } 42 return size; 43 } 44 45 /* 46 * Write an unsigned integer in ULEB128 to the given buffer. The client should 47 * ensure there's enough space in the buffer to hold the result. Update the 48 * given buffer pointer to the point just past the end of the write value and 49 * return the number of bytes being written. 50 */ 51 template <> 52 size_t encode<uint64_t>(ByteType*& pBuf, uint64_t pValue); 53 54 template <> 55 size_t encode<uint32_t>(ByteType*& pBuf, uint32_t pValue); 56 57 /* 58 * Encoding functions for signed LEB128. 59 */ 60 template <> 61 size_t encode<int64_t>(ByteType*& pBuf, int64_t pValue); 62 63 template <> 64 size_t encode<int32_t>(ByteType*& pBuf, int32_t pValue); 65 66 /* 67 * Read an integer encoded in ULEB128 format from the given buffer. pSize will 68 * contain the number of bytes used in the buffer to encode the returned 69 * integer. 70 */ 71 template <> 72 uint64_t decode<uint64_t>(const ByteType* pBuf, size_t& pSize); 73 74 /* 75 * Read an integer encoded in ULEB128 format from the given buffer. Update the 76 * given buffer pointer to the point just past the end of the read value. 77 */ 78 template <> 79 uint64_t decode<uint64_t>(const ByteType*& pBuf); 80 81 /* 82 * Decoding functions for signed LEB128. 83 */ 84 template <> 85 int64_t decode<int64_t>(const ByteType* pBuf, size_t& pSize); 86 87 template <> 88 int64_t decode<int64_t>(const ByteType*& pBuf); 89 90 /* 91 * The functions below handle the signed byte stream. This helps the user to get 92 * rid of annoying type conversions when using the LEB128 encoding/decoding APIs 93 * defined above. 94 */ 95 template <typename IntType> 96 size_t encode(char*& pBuf, IntType pValue) { 97 return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue); 98 } 99 100 template <typename IntType> 101 IntType decode(const char* pBuf, size_t& pSize) { 102 return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize); 103 } 104 105 template <typename IntType> 106 IntType decode(const char*& pBuf) { 107 return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf)); 108 } 109 110 } // namespace leb128 111 } // namespace mcld 112 113 #endif // MCLD_SUPPORT_LEB128_H_ 114