blob: 38b016d16ddc15f39a2d4fa8391024ae749cb516 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
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 * Some handy functions for manipulating bits and bytes.
18 *
19 * These get inlined, so prefer small size over maximum speed.
20 */
21#ifndef _DALVIK_BITS
22#define _DALVIK_BITS
23
24#include "Common.h"
25#include "Inlines.h"
26
27#include <stdlib.h>
28#include <string.h>
29
30/*
31 * Get 1 byte. (Included to make the code more legible.)
32 */
33INLINE u1 get1(unsigned const char* pSrc)
34{
35 return *pSrc;
36}
37
38/*
39 * Get 2 big-endian bytes.
40 */
41INLINE u2 get2BE(unsigned char const* pSrc)
42{
43 return (pSrc[0] << 8) | pSrc[1];
44}
45
46/*
47 * Get 4 big-endian bytes.
48 */
49INLINE u4 get4BE(unsigned char const* pSrc)
50{
51 return (pSrc[0] << 24) | (pSrc[1] << 16) | (pSrc[2] << 8) | pSrc[3];
52}
53
54/*
55 * Get 8 big-endian bytes.
56 */
57INLINE u8 get8BE(unsigned char const* pSrc)
58{
59 u4 low, high;
60
61 high = pSrc[0];
62 high = (high << 8) | pSrc[1];
63 high = (high << 8) | pSrc[2];
64 high = (high << 8) | pSrc[3];
65 low = pSrc[4];
66 low = (low << 8) | pSrc[5];
67 low = (low << 8) | pSrc[6];
68 low = (low << 8) | pSrc[7];
69
70 return ((u8) high << 32) | (u8) low;
71}
72
73/*
74 * Get 2 little-endian bytes.
75 */
76INLINE u2 get2LE(unsigned char const* pSrc)
77{
78 return pSrc[0] | (pSrc[1] << 8);
79}
80
81/*
82 * Get 4 little-endian bytes.
83 */
84INLINE u4 get4LE(unsigned char const* pSrc)
85{
86 u4 result;
87
88 result = pSrc[0];
89 result |= pSrc[1] << 8;
90 result |= pSrc[2] << 16;
91 result |= pSrc[3] << 24;
92
93 return result;
94}
95
96/*
97 * Get 8 little-endian bytes.
98 */
99INLINE u8 get8LE(unsigned char const* pSrc)
100{
101 u4 low, high;
102
103 low = pSrc[0];
104 low |= pSrc[1] << 8;
105 low |= pSrc[2] << 16;
106 low |= pSrc[3] << 24;
107 high = pSrc[4];
108 high |= pSrc[5] << 8;
109 high |= pSrc[6] << 16;
110 high |= pSrc[7] << 24;
111 return ((u8) high << 32) | (u8) low;
112}
113
114/*
115 * Grab 1 byte and advance the data pointer.
116 */
117INLINE u1 read1(unsigned const char** ppSrc)
118{
119 return *(*ppSrc)++;
120}
121
122/*
123 * Grab 2 big-endian bytes and advance the data pointer.
124 */
125INLINE u2 read2BE(unsigned char const** ppSrc)
126{
127 const unsigned char* pSrc = *ppSrc;
128
129 *ppSrc = pSrc + 2;
130 return pSrc[0] << 8 | pSrc[1];
131}
132
133/*
134 * Grab 4 big-endian bytes and advance the data pointer.
135 */
136INLINE u4 read4BE(unsigned char const** ppSrc)
137{
138 const unsigned char* pSrc = *ppSrc;
139 u4 result;
140
141 result = pSrc[0] << 24;
142 result |= pSrc[1] << 16;
143 result |= pSrc[2] << 8;
144 result |= pSrc[3];
145
146 *ppSrc = pSrc + 4;
147 return result;
148}
149
150/*
151 * Get 8 big-endian bytes and advance the data pointer.
152 */
153INLINE u8 read8BE(unsigned char const** ppSrc)
154{
155 const unsigned char* pSrc = *ppSrc;
156 u4 low, high;
157
158 high = pSrc[0];
159 high = (high << 8) | pSrc[1];
160 high = (high << 8) | pSrc[2];
161 high = (high << 8) | pSrc[3];
162 low = pSrc[4];
163 low = (low << 8) | pSrc[5];
164 low = (low << 8) | pSrc[6];
165 low = (low << 8) | pSrc[7];
166
167 *ppSrc = pSrc + 8;
168 return ((u8) high << 32) | (u8) low;
169}
170
171/*
172 * Grab 2 little-endian bytes and advance the data pointer.
173 */
174INLINE u2 read2LE(unsigned char const** ppSrc)
175{
176 const unsigned char* pSrc = *ppSrc;
177 *ppSrc = pSrc + 2;
178 return pSrc[0] | pSrc[1] << 8;
179}
180
181/*
182 * Grab 4 little-endian bytes and advance the data pointer.
183 */
184INLINE u4 read4LE(unsigned char const** ppSrc)
185{
186 const unsigned char* pSrc = *ppSrc;
187 u4 result;
188
189 result = pSrc[0];
190 result |= pSrc[1] << 8;
191 result |= pSrc[2] << 16;
192 result |= pSrc[3] << 24;
193
194 *ppSrc = pSrc + 4;
195 return result;
196}
197
198/*
199 * Get 8 little-endian bytes and advance the data pointer.
200 */
201INLINE u8 read8LE(unsigned char const** ppSrc)
202{
203 const unsigned char* pSrc = *ppSrc;
204 u4 low, high;
205
206 low = pSrc[0];
207 low |= pSrc[1] << 8;
208 low |= pSrc[2] << 16;
209 low |= pSrc[3] << 24;
210 high = pSrc[4];
211 high |= pSrc[5] << 8;
212 high |= pSrc[6] << 16;
213 high |= pSrc[7] << 24;
214
215 *ppSrc = pSrc + 8;
216 return ((u8) high << 32) | (u8) low;
217}
218
219/*
220 * Skip over a UTF-8 string (preceded by a 4-byte length).
221 */
222INLINE void skipUtf8String(unsigned char const** ppSrc)
223{
224 u4 length = read4BE(ppSrc);
225
226 (*ppSrc) += length;
227}
228
229/*
230 * Read a UTF-8 string into a fixed-size buffer, and null-terminate it.
231 *
232 * Returns the length of the original string.
233 */
234INLINE int readUtf8String(unsigned char const** ppSrc, char* buf, size_t bufLen)
235{
236 u4 length = read4BE(ppSrc);
237 size_t copyLen = (length < bufLen) ? length : bufLen-1;
238
239 memcpy(buf, *ppSrc, copyLen);
240 buf[copyLen] = '\0';
241
242 (*ppSrc) += length;
243 return length;
244}
245
246/*
247 * Read a UTF-8 string into newly-allocated storage, and null-terminate it.
248 *
249 * Returns the string and its length. (The latter is probably unnecessary
250 * for the way we're using UTF8.)
251 */
252INLINE char* readNewUtf8String(unsigned char const** ppSrc, size_t* pLength)
253{
254 u4 length = read4BE(ppSrc);
255 char* buf;
256
257 buf = (char*) malloc(length+1);
258
259 memcpy(buf, *ppSrc, length);
260 buf[length] = '\0';
261
262 (*ppSrc) += length;
263
264 *pLength = length;
265 return buf;
266}
267
268
269/*
270 * Set 1 byte. (Included to make code more consistent/legible.)
271 */
272INLINE void set1(u1* buf, u1 val)
273{
274 *buf = (u1)(val);
275}
276
277/*
278 * Set 2 big-endian bytes.
279 */
280INLINE void set2BE(u1* buf, u2 val)
281{
282 *buf++ = (u1)(val >> 8);
283 *buf = (u1)(val);
284}
285
286/*
287 * Set 4 big-endian bytes.
288 */
289INLINE void set4BE(u1* buf, u4 val)
290{
291 *buf++ = (u1)(val >> 24);
292 *buf++ = (u1)(val >> 16);
293 *buf++ = (u1)(val >> 8);
294 *buf = (u1)(val);
295}
296
297/*
298 * Set 8 big-endian bytes.
299 */
300INLINE void set8BE(u1* buf, u8 val)
301{
302 *buf++ = (u1)(val >> 56);
303 *buf++ = (u1)(val >> 48);
304 *buf++ = (u1)(val >> 40);
305 *buf++ = (u1)(val >> 32);
306 *buf++ = (u1)(val >> 24);
307 *buf++ = (u1)(val >> 16);
308 *buf++ = (u1)(val >> 8);
309 *buf = (u1)(val);
310}
311
312/*
313 * Set 2 little-endian bytes.
314 */
315INLINE void set2LE(u1* buf, u2 val)
316{
317 *buf++ = (u1)(val);
318 *buf = (u1)(val >> 8);
319}
320
321/*
322 * Set 4 little-endian bytes.
323 */
324INLINE void set4LE(u1* buf, u4 val)
325{
326 *buf++ = (u1)(val);
327 *buf++ = (u1)(val >> 8);
328 *buf++ = (u1)(val >> 16);
329 *buf = (u1)(val >> 24);
330}
331
332/*
333 * Set 8 little-endian bytes.
334 */
335INLINE void set8LE(u1* buf, u8 val)
336{
337 *buf++ = (u1)(val);
338 *buf++ = (u1)(val >> 8);
339 *buf++ = (u1)(val >> 16);
340 *buf++ = (u1)(val >> 24);
341 *buf++ = (u1)(val >> 32);
342 *buf++ = (u1)(val >> 40);
343 *buf++ = (u1)(val >> 48);
344 *buf = (u1)(val >> 56);
345}
346
347/*
348 * Stuff a UTF-8 string into the buffer.
349 */
350INLINE void setUtf8String(u1* buf, const u1* str)
351{
352 u4 strLen = strlen((const char*)str);
353
354 set4BE(buf, strLen);
355 memcpy(buf + sizeof(u4), str, strLen);
356}
357
358#endif /*_DALVIK_BITS*/