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