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