LEB128.h revision 37b74a387bb3993387029859c2d9d051c41c724e
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 15namespace mcld { 16 17namespace leb128 { 18 19typedef unsigned char ByteType; 20 21/* Forward declarations */ 22template <typename IntType> 23size_t encode(ByteType*& pBuf, IntType pValue); 24 25template <typename IntType> 26IntType decode(const ByteType* pBuf, size_t& pSize); 27 28template <typename IntType> 29IntType 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 */ 35template <typename IntType> 36size_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 */ 51template <> 52size_t encode<uint64_t>(ByteType*& pBuf, uint64_t pValue); 53 54template <> 55size_t encode<uint32_t>(ByteType*& pBuf, uint32_t pValue); 56 57/* 58 * Encoding functions for signed LEB128. 59 */ 60template <> 61size_t encode<int64_t>(ByteType*& pBuf, int64_t pValue); 62 63template <> 64size_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 */ 71template <> 72uint64_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 */ 78template <> 79uint64_t decode<uint64_t>(const ByteType*& pBuf); 80 81/* 82 * Decoding functions for signed LEB128. 83 */ 84template <> 85int64_t decode<int64_t>(const ByteType* pBuf, size_t& pSize); 86 87template <> 88int64_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 */ 95template <typename IntType> 96size_t encode(char*& pBuf, IntType pValue) { 97 return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue); 98} 99 100template <typename IntType> 101IntType decode(const char* pBuf, size_t& pSize) { 102 return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize); 103} 104 105template <typename IntType> 106IntType 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