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