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