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