OSDN Git Service

am f4b9e275: am 8bfb6dec: am bb8c2f35: am bdd06aad: Fix a type error in the allocatio...
[android-x86/dalvik.git] / libdex / Leb128.h
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * Functions for interpreting LEB128 (little endian base 128) values
19  */
20
21 #ifndef _LIBDEX_LEB128
22 #define _LIBDEX_LEB128
23
24 #include "DexFile.h"
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 /*
31  * Reads an unsigned LEB128 value, updating the given pointer to point
32  * just past the end of the read value. This function tolerates
33  * non-zero high-order bits in the fifth encoded byte.
34  */
35 DEX_INLINE int readUnsignedLeb128(const u1** pStream) {
36     const u1* ptr = *pStream;
37     int result = *(ptr++);
38
39     if (result > 0x7f) {
40         int cur = *(ptr++);
41         result = (result & 0x7f) | ((cur & 0x7f) << 7);
42         if (cur > 0x7f) {
43             cur = *(ptr++);
44             result |= (cur & 0x7f) << 14;
45             if (cur > 0x7f) {
46                 cur = *(ptr++);
47                 result |= (cur & 0x7f) << 21;
48                 if (cur > 0x7f) {
49                     /*
50                      * Note: We don't check to see if cur is out of
51                      * range here, meaning we tolerate garbage in the
52                      * high four-order bits.
53                      */
54                     cur = *(ptr++);
55                     result |= cur << 28;
56                 }
57             }
58         }
59     }
60
61     *pStream = ptr;
62     return result;
63 }
64
65 /*
66  * Reads a signed LEB128 value, updating the given pointer to point
67  * just past the end of the read value. This function tolerates
68  * non-zero high-order bits in the fifth encoded byte.
69  */
70 DEX_INLINE int readSignedLeb128(const u1** pStream) {
71     const u1* ptr = *pStream;
72     int result = *(ptr++);
73
74     if (result <= 0x7f) {
75         result = (result << 25) >> 25;
76     } else {
77         int cur = *(ptr++);
78         result = (result & 0x7f) | ((cur & 0x7f) << 7);
79         if (cur <= 0x7f) {
80             result = (result << 18) >> 18;
81         } else {
82             cur = *(ptr++);
83             result |= (cur & 0x7f) << 14;
84             if (cur <= 0x7f) {
85                 result = (result << 11) >> 11;
86             } else {
87                 cur = *(ptr++);
88                 result |= (cur & 0x7f) << 21;
89                 if (cur <= 0x7f) {
90                     result = (result << 4) >> 4;
91                 } else {
92                     /*
93                      * Note: We don't check to see if cur is out of
94                      * range here, meaning we tolerate garbage in the
95                      * high four-order bits.
96                      */
97                     cur = *(ptr++);
98                     result |= cur << 28;
99                 }
100             }
101         }
102     }
103
104     *pStream = ptr;
105     return result;
106 }
107
108 /*
109  * Reads an unsigned LEB128 value, updating the given pointer to point
110  * just past the end of the read value and also indicating whether the
111  * value was syntactically valid. The only syntactically *invalid*
112  * values are ones that are five bytes long where the final byte has
113  * any but the low-order four bits set. Additionally, if the limit is
114  * passed as non-NULL and bytes would need to be read past the limit,
115  * then the read is considered invalid.
116  */
117 int readAndVerifyUnsignedLeb128(const u1** pStream, const u1* limit,
118         bool* okay);
119
120 /*
121  * Reads a signed LEB128 value, updating the given pointer to point
122  * just past the end of the read value and also indicating whether the
123  * value was syntactically valid. The only syntactically *invalid*
124  * values are ones that are five bytes long where the final byte has
125  * any but the low-order four bits set. Additionally, if the limit is
126  * passed as non-NULL and bytes would need to be read past the limit,
127  * then the read is considered invalid.
128  */
129 int readAndVerifySignedLeb128(const u1** pStream, const u1* limit, bool* okay);
130
131
132 /*
133  * Writes a 32-bit value in unsigned ULEB128 format.
134  *
135  * Returns the updated pointer.
136  */
137 DEX_INLINE u1* writeUnsignedLeb128(u1* ptr, u4 data)
138 {
139     while (true) {
140         u1 out = data & 0x7f;
141         if (out != data) {
142             *ptr++ = out | 0x80;
143             data >>= 7;
144         } else {
145             *ptr++ = out;
146             break;
147         }
148     }
149
150     return ptr;
151 }
152
153 /*
154  * Returns the number of bytes needed to encode "val" in ULEB128 form.
155  */
156 DEX_INLINE int unsignedLeb128Size(u4 data)
157 {
158     int count = 0;
159
160     do {
161         data >>= 7;
162         count++;
163     } while (data != 0);
164
165     return count;
166 }
167
168 #ifdef __cplusplus
169 }
170 #endif
171
172 #endif