• 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_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