| //===- LEB128.h -----------------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef MCLD_LEB128_H |
| #define MCLD_LEB128_H |
| #ifdef ENABLE_UNITTEST |
| #include <gtest.h> |
| #endif |
| |
| #include <stdint.h> |
| #include <sys/types.h> |
| |
| namespace mcld { |
| |
| namespace leb128 { |
| |
| typedef unsigned char ByteType; |
| |
| /* Forward declarations */ |
| template<typename IntType> |
| size_t encode(ByteType *&pBuf, IntType pValue); |
| |
| template<typename IntType> |
| IntType decode(const ByteType *pBuf, size_t &pSize); |
| |
| template<typename IntType> |
| IntType decode(const ByteType *&pBuf); |
| |
| /* |
| * Given an integer, this function returns the number of bytes required to |
| * encode it in ULEB128 format. |
| */ |
| template<typename IntType> |
| size_t size(IntType pValue) { |
| size_t size = 1; |
| while (pValue > 0x80) { |
| pValue >>= 7; |
| ++size; |
| } |
| return size; |
| } |
| |
| /* |
| * Write an unsigned integer in ULEB128 to the given buffer. The client should |
| * ensure there's enough space in the buffer to hold the result. Update the |
| * given buffer pointer to the point just past the end of the write value and |
| * return the number of bytes being written. |
| */ |
| template<> |
| size_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue); |
| |
| template<> |
| size_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue); |
| |
| /* |
| * Encoding functions for signed LEB128. |
| */ |
| template<> |
| size_t encode<int64_t>(ByteType *&pBuf, int64_t pValue); |
| |
| template<> |
| size_t encode<int32_t>(ByteType *&pBuf, int32_t pValue); |
| |
| /* |
| * Read an integer encoded in ULEB128 format from the given buffer. pSize will |
| * contain the number of bytes used in the buffer to encode the returned |
| * integer. |
| */ |
| template<> |
| uint64_t decode<uint64_t>(const ByteType *pBuf, size_t &pSize); |
| |
| /* |
| * Read an integer encoded in ULEB128 format from the given buffer. Update the |
| * given buffer pointer to the point just past the end of the read value. |
| */ |
| template<> |
| uint64_t decode<uint64_t>(const ByteType *&pBuf); |
| |
| /* |
| * Decoding functions for signed LEB128. |
| */ |
| template<> |
| int64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize); |
| |
| template<> |
| int64_t decode<int64_t>(const ByteType *&pBuf); |
| |
| /* |
| * The functions below handle the signed byte stream. This helps the user to get |
| * rid of annoying type conversions when using the LEB128 encoding/decoding APIs |
| * defined above. |
| */ |
| template<typename IntType> |
| size_t encode(char *&pBuf, IntType pValue) { |
| return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue); |
| } |
| |
| template<typename IntType> |
| IntType decode(const char *pBuf, size_t &pSize) { |
| return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize); |
| } |
| |
| template<typename IntType> |
| IntType decode(const char *&pBuf) { |
| return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf)); |
| } |
| |
| } // namespace of leb128 |
| } // namespace of mcld |
| |
| #endif |