blob: 2c6c1c8693ac5fdafd26f195bed0433472ebe09d [file] [log] [blame]
//===- LEB128.h -----------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCLD_SUPPORT_LEB128_H_
#define MCLD_SUPPORT_LEB128_H_
#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 leb128
} // namespace mcld
#endif // MCLD_SUPPORT_LEB128_H_