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