LEB128.h revision 533eae20118036f425f27bf0536ef0ccbb090b65
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
10#ifndef MCLD_SUPPORT_LEB128_H
11#define MCLD_SUPPORT_LEB128_H
12
13#include <stdint.h>
14#include <sys/types.h>
15
16namespace mcld {
17
18namespace leb128 {
19
20typedef unsigned char ByteType;
21
22/* Forward declarations */
23template<typename IntType>
24size_t encode(ByteType *&pBuf, IntType pValue);
25
26template<typename IntType>
27IntType decode(const ByteType *pBuf, size_t &pSize);
28
29template<typename IntType>
30IntType decode(const ByteType *&pBuf);
31
32/*
33 * Given an integer, this function returns the number of bytes required to
34 * encode it in ULEB128 format.
35 */
36template<typename IntType>
37size_t size(IntType pValue) {
38  size_t size = 1;
39  while (pValue > 0x80) {
40    pValue >>= 7;
41    ++size;
42  }
43  return size;
44}
45
46/*
47 * Write an unsigned integer in ULEB128 to the given buffer. The client should
48 * ensure there's enough space in the buffer to hold the result. Update the
49 * given buffer pointer to the point just past the end of the write value and
50 * return the number of bytes being written.
51 */
52template<>
53size_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue);
54
55template<>
56size_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue);
57
58/*
59 * Encoding functions for signed LEB128.
60 */
61template<>
62size_t encode<int64_t>(ByteType *&pBuf, int64_t pValue);
63
64template<>
65size_t encode<int32_t>(ByteType *&pBuf, int32_t pValue);
66
67/*
68 * Read an integer encoded in ULEB128 format from the given buffer. pSize will
69 * contain the number of bytes used in the buffer to encode the returned
70 * integer.
71 */
72template<>
73uint64_t decode<uint64_t>(const ByteType *pBuf, size_t &pSize);
74
75/*
76 * Read an integer encoded in ULEB128 format from the given buffer. Update the
77 * given buffer pointer to the point just past the end of the read value.
78 */
79template<>
80uint64_t decode<uint64_t>(const ByteType *&pBuf);
81
82/*
83 * Decoding functions for signed LEB128.
84 */
85template<>
86int64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize);
87
88template<>
89int64_t decode<int64_t>(const ByteType *&pBuf);
90
91/*
92 * The functions below handle the signed byte stream. This helps the user to get
93 * rid of annoying type conversions when using the LEB128 encoding/decoding APIs
94 * defined above.
95 */
96template<typename IntType>
97size_t encode(char *&pBuf, IntType pValue) {
98  return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue);
99}
100
101template<typename IntType>
102IntType decode(const char *pBuf, size_t &pSize) {
103  return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize);
104}
105
106template<typename IntType>
107IntType decode(const char *&pBuf) {
108  return decode<IntType>(reinterpret_cast<const ByteType*&>(pBuf));
109}
110
111} // namespace of leb128
112} // namespace of mcld
113
114#endif
115