crazy_linker_leb128.h revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CRAZY_LINKER_LEB128_H
6#define CRAZY_LINKER_LEB128_H
7
8#include <stdint.h>
9
10// Helper classes for decoding LEB128, used in packed relocation data.
11// http://en.wikipedia.org/wiki/LEB128
12
13namespace crazy {
14
15class Leb128Decoder {
16 public:
17  explicit Leb128Decoder(const uint8_t* encoding)
18      : encoding_(encoding), cursor_(0) { }
19
20  size_t Dequeue() {
21    uint32_t value = 0;
22
23    size_t shift = 0;
24    uint8_t byte;
25
26    do {
27      byte = encoding_[cursor_++];
28      value |= static_cast<uint32_t>(byte & 127) << shift;
29      shift += 7;
30    } while (byte & 128);
31
32    return value;
33  }
34
35 private:
36  const uint8_t* encoding_;
37  size_t cursor_;
38};
39
40class Sleb128Decoder {
41 public:
42  explicit Sleb128Decoder(const uint8_t* encoding)
43      : encoding_(encoding), cursor_(0) { }
44
45  ssize_t Dequeue() {
46    ssize_t value = 0;
47    static const size_t size = CHAR_BIT * sizeof(value);
48
49    size_t shift = 0;
50    uint8_t byte;
51
52    do {
53      byte = encoding_[cursor_++];
54      value |= (static_cast<ssize_t>(byte & 127) << shift);
55      shift += 7;
56    } while (byte & 128);
57
58    if (shift < size && (byte & 64))
59      value |= -(static_cast<ssize_t>(1) << shift);
60
61    return value;
62  }
63
64 private:
65  const uint8_t* encoding_;
66  size_t cursor_;
67};
68
69}  // namespace crazy
70
71#endif  // CRAZY_LINKER_LEB128_H
72