12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
161fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_LEB128_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_LEB128_H_
191fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
2041b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko#include <vector>
2141b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko
2241b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko#include "base/bit_utils.h"
2341b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko#include "base/logging.h"
24578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h"
251fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
261fb8620309a4e94d11879aabc33364acfa733904Carl Shapironamespace art {
271fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
281fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// Reads an unsigned LEB128 value, updating the given pointer to point
291fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// just past the end of the read value. This function tolerates
301fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// non-zero high-order bits in the fifth encoded byte.
3196faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogersstatic inline uint32_t DecodeUnsignedLeb128(const uint8_t** data) {
3296faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  const uint8_t* ptr = *data;
331fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  int result = *(ptr++);
341ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  if (UNLIKELY(result > 0x7f)) {
351fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    int cur = *(ptr++);
361fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    result = (result & 0x7f) | ((cur & 0x7f) << 7);
371fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    if (cur > 0x7f) {
381fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      cur = *(ptr++);
391fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      result |= (cur & 0x7f) << 14;
401fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      if (cur > 0x7f) {
411fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        cur = *(ptr++);
421fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        result |= (cur & 0x7f) << 21;
431fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        if (cur > 0x7f) {
441fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          // Note: We don't check to see if cur is out of range here,
451fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          // meaning we tolerate garbage in the four high-order bits.
461fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          cur = *(ptr++);
471fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          result |= cur << 28;
481fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        }
491fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      }
501fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    }
511fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  }
521fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  *data = ptr;
53cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  return static_cast<uint32_t>(result);
541fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}
551fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
56195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao// Reads an unsigned LEB128 + 1 value. updating the given pointer to point
57195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao// just past the end of the read value. This function tolerates
58195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao// non-zero high-order bits in the fifth encoded byte.
59195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao// It is possible for this function to return -1.
6096faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogersstatic inline int32_t DecodeUnsignedLeb128P1(const uint8_t** data) {
61195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao  return DecodeUnsignedLeb128(data) - 1;
62195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao}
63195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao
641fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// Reads a signed LEB128 value, updating the given pointer to point
651fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// just past the end of the read value. This function tolerates
661fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// non-zero high-order bits in the fifth encoded byte.
6796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogersstatic inline int32_t DecodeSignedLeb128(const uint8_t** data) {
6896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  const uint8_t* ptr = *data;
691fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  int32_t result = *(ptr++);
701fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  if (result <= 0x7f) {
711fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    result = (result << 25) >> 25;
721fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  } else {
731fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    int cur = *(ptr++);
741fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    result = (result & 0x7f) | ((cur & 0x7f) << 7);
751fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    if (cur <= 0x7f) {
761fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      result = (result << 18) >> 18;
771fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    } else {
781fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      cur = *(ptr++);
791fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      result |= (cur & 0x7f) << 14;
801fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      if (cur <= 0x7f) {
811fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        result = (result << 11) >> 11;
821fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      } else {
831fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        cur = *(ptr++);
841fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        result |= (cur & 0x7f) << 21;
851fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        if (cur <= 0x7f) {
861fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          result = (result << 4) >> 4;
871fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        } else {
881fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          // Note: We don't check to see if cur is out of range here,
891fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          // meaning we tolerate garbage in the four high-order bits.
901fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          cur = *(ptr++);
911fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          result |= cur << 28;
921fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        }
931fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      }
941fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    }
951fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  }
961fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  *data = ptr;
971fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  return result;
981fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}
991fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
100d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao// Returns the number of bytes needed to encode the value in unsigned LEB128.
101d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhaostatic inline uint32_t UnsignedLeb128Size(uint32_t data) {
1021e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  // bits_to_encode = (data != 0) ? 32 - CLZ(x) : 1  // 32 - CLZ(data | 1)
1031e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  // bytes = ceil(bits_to_encode / 7.0);             // (6 + bits_to_encode) / 7
1041e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t x = 6 + 32 - CLZ(data | 1);
1051e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  // Division by 7 is done by (x * 37) >> 8 where 37 = ceil(256 / 7).
1061e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  // This works for 0 <= x < 256 / (7 * 37 - 256), i.e. 0 <= x <= 85.
1071e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  return (x * 37) >> 8;
1081e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko}
1091e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko
1101e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko// Returns the number of bytes needed to encode the value in unsigned LEB128.
1111e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Markostatic inline uint32_t SignedLeb128Size(int32_t data) {
1121e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  // Like UnsignedLeb128Size(), but we need one bit beyond the highest bit that differs from sign.
1131e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  data = data ^ (data >> 31);
1141e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  uint32_t x = 1 /* we need to encode the sign bit */ + 6 + 32 - CLZ(data | 1);
1151e6cb63d77090ddc6aa19c755d7066f66e9ff87eVladimir Marko  return (x * 37) >> 8;
116d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao}
117d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao
118a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromstatic inline uint8_t* EncodeUnsignedLeb128(uint8_t* dest, uint32_t value) {
119a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  uint8_t out = value & 0x7f;
120a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  value >>= 7;
121a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  while (value != 0) {
122a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    *dest++ = out | 0x80;
123a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    out = value & 0x7f;
124a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    value >>= 7;
125a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
126a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  *dest++ = out;
127a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  return dest;
128a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom}
129a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
13015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbeckytemplate<typename Allocator>
13115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbeckystatic inline void EncodeUnsignedLeb128(std::vector<uint8_t, Allocator>* dest, uint32_t value) {
13215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  uint8_t out = value & 0x7f;
13315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  value >>= 7;
13415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  while (value != 0) {
13515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    dest->push_back(out | 0x80);
13615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    out = value & 0x7f;
13715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    value >>= 7;
13815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
13915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  dest->push_back(out);
14015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky}
14115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
142b536247b1ce5de640eec81dddac47802cd074363David Srbecky// Overwrite encoded Leb128 with a new value. The new value must be less than
143b536247b1ce5de640eec81dddac47802cd074363David Srbecky// or equal to the old value to ensure that it fits the allocated space.
144b536247b1ce5de640eec81dddac47802cd074363David Srbeckystatic inline void UpdateUnsignedLeb128(uint8_t* dest, uint32_t value) {
145b536247b1ce5de640eec81dddac47802cd074363David Srbecky  const uint8_t* old_end = dest;
146b536247b1ce5de640eec81dddac47802cd074363David Srbecky  uint32_t old_value = DecodeUnsignedLeb128(&old_end);
147b536247b1ce5de640eec81dddac47802cd074363David Srbecky  DCHECK_LE(value, old_value);
148b536247b1ce5de640eec81dddac47802cd074363David Srbecky  for (uint8_t* end = EncodeUnsignedLeb128(dest, value); end < old_end; end++) {
149b536247b1ce5de640eec81dddac47802cd074363David Srbecky    // Use longer encoding than necessary to fill the allocated space.
150b536247b1ce5de640eec81dddac47802cd074363David Srbecky    end[-1] |= 0x80;
151b536247b1ce5de640eec81dddac47802cd074363David Srbecky    end[0] = 0;
152b536247b1ce5de640eec81dddac47802cd074363David Srbecky  }
153b536247b1ce5de640eec81dddac47802cd074363David Srbecky}
154b536247b1ce5de640eec81dddac47802cd074363David Srbecky
155a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstromstatic inline uint8_t* EncodeSignedLeb128(uint8_t* dest, int32_t value) {
156a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  uint32_t extra_bits = static_cast<uint32_t>(value ^ (value >> 31)) >> 6;
157a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  uint8_t out = value & 0x7f;
158a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  while (extra_bits != 0u) {
159a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    *dest++ = out | 0x80;
160a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    value >>= 7;
161a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    out = value & 0x7f;
162a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    extra_bits >>= 7;
163a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
164a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  *dest++ = out;
165a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  return dest;
166a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom}
167a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
16815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbeckytemplate<typename Allocator>
16915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbeckystatic inline void EncodeSignedLeb128(std::vector<uint8_t, Allocator>* dest, int32_t value) {
17015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  uint32_t extra_bits = static_cast<uint32_t>(value ^ (value >> 31)) >> 6;
17115c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  uint8_t out = value & 0x7f;
17215c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  while (extra_bits != 0u) {
17315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    dest->push_back(out | 0x80);
17415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    value >>= 7;
17515c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    out = value & 0x7f;
17615c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    extra_bits >>= 7;
17715c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  }
17815c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky  dest->push_back(out);
17915c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky}
18015c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky
181e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban// An encoder that pushed uint32_t data onto the given std::vector.
182e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanclass Leb128Encoder {
183a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom public:
184e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  explicit Leb128Encoder(std::vector<uint8_t>* data) : data_(data) {
185e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    DCHECK(data != nullptr);
186a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
187a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
188a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  void Reserve(uint32_t size) {
189e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    data_->reserve(size);
190a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
191a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
192a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  void PushBackUnsigned(uint32_t value) {
19315c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    EncodeUnsignedLeb128(data_, value);
194a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
195a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
196a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  template<typename It>
197a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  void InsertBackUnsigned(It cur, It end) {
198a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    for (; cur != end; ++cur) {
199a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      PushBackUnsigned(*cur);
200a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    }
201a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
202a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
203a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  void PushBackSigned(int32_t value) {
20415c1975f5fa5ae646ae87b57394bfdae1090a236David Srbecky    EncodeSignedLeb128(data_, value);
205a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
206a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
207a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  template<typename It>
208a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  void InsertBackSigned(It cur, It end) {
209a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    for (; cur != end; ++cur) {
210a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom      PushBackSigned(*cur);
211a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    }
212a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
213a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
214a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  const std::vector<uint8_t>& GetData() const {
215e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    return *data_;
216a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  }
217a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
218e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban protected:
219e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  std::vector<uint8_t>* const data_;
220e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
221a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom private:
222e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  DISALLOW_COPY_AND_ASSIGN(Leb128Encoder);
223e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban};
224e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
225e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban// An encoder with an API similar to vector<uint32_t> where the data is captured in ULEB128 format.
226e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanclass Leb128EncodingVector FINAL : private std::vector<uint8_t>, public Leb128Encoder {
227e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban public:
228e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  Leb128EncodingVector() : Leb128Encoder(this) {
229e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
230a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
231e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban private:
232a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom  DISALLOW_COPY_AND_ASSIGN(Leb128EncodingVector);
233a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom};
234a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom
2351fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}  // namespace art
2361fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
237fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_LEB128_H_
238