leb128.h revision 96faf5b363d922ae91cf25404dee0e87c740c7c5
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
20578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "globals.h"
211fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
221fb8620309a4e94d11879aabc33364acfa733904Carl Shapironamespace art {
231fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
241fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// Reads an unsigned LEB128 value, updating the given pointer to point
251fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// just past the end of the read value. This function tolerates
261fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// non-zero high-order bits in the fifth encoded byte.
2796faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogersstatic inline uint32_t DecodeUnsignedLeb128(const uint8_t** data) {
2896faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  const uint8_t* ptr = *data;
291fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  int result = *(ptr++);
301fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  if (result > 0x7f) {
311fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    int cur = *(ptr++);
321fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    result = (result & 0x7f) | ((cur & 0x7f) << 7);
331fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    if (cur > 0x7f) {
341fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      cur = *(ptr++);
351fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      result |= (cur & 0x7f) << 14;
361fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      if (cur > 0x7f) {
371fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        cur = *(ptr++);
381fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        result |= (cur & 0x7f) << 21;
391fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        if (cur > 0x7f) {
401fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          // Note: We don't check to see if cur is out of range here,
411fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          // meaning we tolerate garbage in the four high-order bits.
421fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          cur = *(ptr++);
431fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          result |= cur << 28;
441fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        }
451fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      }
461fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    }
471fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  }
481fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  *data = ptr;
49cbd6d44c0a94f3d26671b5325aa21bbf1335ffe8buzbee  return static_cast<uint32_t>(result);
501fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}
511fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
52195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao// Reads an unsigned LEB128 + 1 value. updating the given pointer to point
53195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao// just past the end of the read value. This function tolerates
54195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao// non-zero high-order bits in the fifth encoded byte.
55195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao// It is possible for this function to return -1.
5696faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogersstatic inline int32_t DecodeUnsignedLeb128P1(const uint8_t** data) {
57195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao  return DecodeUnsignedLeb128(data) - 1;
58195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao}
59195487cb0b11e64917df01f8d55671344db2e97fShih-wei Liao
601fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// Reads a signed LEB128 value, updating the given pointer to point
611fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// just past the end of the read value. This function tolerates
621fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro// non-zero high-order bits in the fifth encoded byte.
6396faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogersstatic inline int32_t DecodeSignedLeb128(const uint8_t** data) {
6496faf5b363d922ae91cf25404dee0e87c740c7c5Ian Rogers  const uint8_t* ptr = *data;
651fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  int32_t result = *(ptr++);
661fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  if (result <= 0x7f) {
671fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    result = (result << 25) >> 25;
681fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  } else {
691fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    int cur = *(ptr++);
701fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    result = (result & 0x7f) | ((cur & 0x7f) << 7);
711fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    if (cur <= 0x7f) {
721fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      result = (result << 18) >> 18;
731fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    } else {
741fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      cur = *(ptr++);
751fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      result |= (cur & 0x7f) << 14;
761fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      if (cur <= 0x7f) {
771fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        result = (result << 11) >> 11;
781fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      } else {
791fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        cur = *(ptr++);
801fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        result |= (cur & 0x7f) << 21;
811fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        if (cur <= 0x7f) {
821fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          result = (result << 4) >> 4;
831fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        } else {
841fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          // Note: We don't check to see if cur is out of range here,
851fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          // meaning we tolerate garbage in the four high-order bits.
861fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          cur = *(ptr++);
871fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro          result |= cur << 28;
881fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro        }
891fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro      }
901fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro    }
911fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  }
921fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  *data = ptr;
931fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro  return result;
941fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}
951fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
96d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao// Returns the number of bytes needed to encode the value in unsigned LEB128.
97d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhaostatic inline uint32_t UnsignedLeb128Size(uint32_t data) {
98d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao  uint32_t count = 0;
99d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao  do {
100d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao    data >>= 7;
101d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao    count++;
102d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao  } while (data != 0);
103d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao  return count;
104d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao}
105d1f0fdedff1dac7249e1ed61ddc52a09265c138fjeffhao
1061fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro}  // namespace art
1071fb8620309a4e94d11879aabc33364acfa733904Carl Shapiro
108fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_LEB128_H_
109