LEB128.h revision 5460a1f25d9ddecb5c70667267d66d51af177a99
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
19namespace mcld {
20
21namespace leb128 {
22
23typedef unsigned char ByteType;
24
25/* Forward declarations */
26template<typename IntType>
27size_t encode(ByteType *&pBuf, IntType pValue);
28
29template<typename IntType>
30IntType decode(const ByteType *pBuf, size_t &pSize);
31
32template<typename IntType>
33IntType 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 */
39template<typename IntType>
40size_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 */
55template<>
56size_t encode<uint64_t>(ByteType *&pBuf, uint64_t pValue);
57
58template<>
59size_t encode<uint32_t>(ByteType *&pBuf, uint32_t pValue);
60
61/*
62 * Encoding functions for signed LEB128.
63 */
64template<>
65size_t encode<int64_t>(ByteType *&pBuf, int64_t pValue);
66
67template<>
68size_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 */
75template<>
76uint64_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 */
82template<>
83uint64_t decode<uint64_t>(const ByteType *&pBuf);
84
85/*
86 * Decoding functions for signed LEB128.
87 */
88template<>
89int64_t decode<int64_t>(const ByteType *pBuf, size_t &pSize);
90
91template<>
92int64_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 */
99template<typename IntType>
100size_t encode(char *&pBuf, IntType pValue) {
101  return encode<IntType>(reinterpret_cast<ByteType*&>(pBuf), pValue);
102}
103
104template<typename IntType>
105IntType decode(const char *pBuf, size_t &pSize) {
106  return decode<IntType>(reinterpret_cast<const ByteType*>(pBuf), pSize);
107}
108
109template<typename IntType>
110IntType 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