blob: 816ed72bda2e0cdb95bac7bf98927a03d4464a60 [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_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