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
15 namespace mcld {
16
17 namespace leb128 {
18
19 typedef unsigned char ByteType;
20
21 /* Forward declarations */
22 template <typename IntType>
23 size_t encode(ByteType*& pBuf, IntType pValue);
24
25 template <typename IntType>
26 IntType decode(const ByteType* pBuf, size_t& pSize);
27
28 template <typename IntType>
29 IntType 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 */
35 template <typename IntType>
size(IntType pValue)36 size_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 */
51 template <>
52 size_t encode<uint64_t>(ByteType*& pBuf, uint64_t pValue);
53
54 template <>
55 size_t encode<uint32_t>(ByteType*& pBuf, uint32_t pValue);
56
57 /*
58 * Encoding functions for signed LEB128.
59 */
60 template <>
61 size_t encode<int64_t>(ByteType*& pBuf, int64_t pValue);
62
63 template <>
64 size_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 */
71 template <>
72 uint64_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 */
78 template <>
79 uint64_t decode<uint64_t>(const ByteType*& pBuf);
80
81 /*
82 * Decoding functions for signed LEB128.
83 */
84 template <>
85 int64_t decode<int64_t>(const ByteType* pBuf, size_t& pSize);
86
87 template <>
88 int64_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 */
95 template <typename IntType>
encode(char * & pBuf,IntType pValue)96 size_t encode(char*& pBuf, IntType pValue) {
97 return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue);
98 }
99
100 template <typename IntType>
decode(const char * pBuf,size_t & pSize)101 IntType decode(const char* pBuf, size_t& pSize) {
102 return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize);
103 }
104
105 template <typename IntType>
decode(const char * & pBuf)106 IntType 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