//===- 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