LEB128.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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#ifdef ENABLE_UNITTEST 13#include <gtest.h> 14#endif 15 16#include <stdint.h> 17#include <sys/types.h> 18 19namespace mcld { 20 21namespace leb128 { 22 23typedef unsigned char ByteType; 24 25/* Forward declarations */ 26template<typename IntType> 27size_t encode(ByteType *&pBuf, IntType pValue); 28 29template<typename IntType> 30IntType decode(const ByteType *pBuf, size_t &pSize); 31 32template<typename IntType> 33IntType 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 */ 39template<typename IntType> 40size_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 */ 55template<> 56size_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue); 57 58template<> 59size_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue); 60 61/* 62 * Encoding functions for signed LEB128. 63 */ 64template<> 65size_t encode<int64_t>(ByteType *&pBuf, int64_t pValue); 66 67template<> 68size_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 */ 75template<> 76uint64_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 */ 82template<> 83uint64_t decode<uint64_t>(const ByteType *&pBuf); 84 85/* 86 * Decoding functions for signed LEB128. 87 */ 88template<> 89int64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize); 90 91template<> 92int64_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 */ 99template<typename IntType> 100size_t encode(char *&pBuf, IntType pValue) { 101 return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue); 102} 103 104template<typename IntType> 105IntType decode(const char *pBuf, size_t &pSize) { 106 return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize); 107} 108 109template<typename IntType> 110IntType 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