• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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