2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * Some handy functions for manipulating bits and bytes.
19 * These get inlined, so prefer small size over maximum speed.
21 #ifndef DALVIK_BITS_H_
22 #define DALVIK_BITS_H_
31 * Get 1 byte. (Included to make the code more legible.)
33 INLINE u1 get1(unsigned const char* pSrc)
39 * Get 2 big-endian bytes.
41 INLINE u2 get2BE(unsigned char const* pSrc)
43 return (pSrc[0] << 8) | pSrc[1];
47 * Get 4 big-endian bytes.
49 INLINE u4 get4BE(unsigned char const* pSrc)
51 return (pSrc[0] << 24) | (pSrc[1] << 16) | (pSrc[2] << 8) | pSrc[3];
55 * Get 8 big-endian bytes.
57 INLINE u8 get8BE(unsigned char const* pSrc)
62 high = (high << 8) | pSrc[1];
63 high = (high << 8) | pSrc[2];
64 high = (high << 8) | pSrc[3];
66 low = (low << 8) | pSrc[5];
67 low = (low << 8) | pSrc[6];
68 low = (low << 8) | pSrc[7];
70 return ((u8) high << 32) | (u8) low;
74 * Get 2 little-endian bytes.
76 INLINE u2 get2LE(unsigned char const* pSrc)
78 return pSrc[0] | (pSrc[1] << 8);
82 * Get 4 little-endian bytes.
84 INLINE u4 get4LE(unsigned char const* pSrc)
89 result |= pSrc[1] << 8;
90 result |= pSrc[2] << 16;
91 result |= pSrc[3] << 24;
97 * Get 8 little-endian bytes.
99 INLINE u8 get8LE(unsigned char const* pSrc)
105 low |= pSrc[2] << 16;
106 low |= pSrc[3] << 24;
108 high |= pSrc[5] << 8;
109 high |= pSrc[6] << 16;
110 high |= pSrc[7] << 24;
111 return ((u8) high << 32) | (u8) low;
115 * Grab 1 byte and advance the data pointer.
117 INLINE u1 read1(unsigned const char** ppSrc)
123 * Grab 2 big-endian bytes and advance the data pointer.
125 INLINE u2 read2BE(unsigned char const** ppSrc)
127 const unsigned char* pSrc = *ppSrc;
130 return pSrc[0] << 8 | pSrc[1];
134 * Grab 4 big-endian bytes and advance the data pointer.
136 INLINE u4 read4BE(unsigned char const** ppSrc)
138 const unsigned char* pSrc = *ppSrc;
141 result = pSrc[0] << 24;
142 result |= pSrc[1] << 16;
143 result |= pSrc[2] << 8;
151 * Get 8 big-endian bytes and advance the data pointer.
153 INLINE u8 read8BE(unsigned char const** ppSrc)
155 const unsigned char* pSrc = *ppSrc;
159 high = (high << 8) | pSrc[1];
160 high = (high << 8) | pSrc[2];
161 high = (high << 8) | pSrc[3];
163 low = (low << 8) | pSrc[5];
164 low = (low << 8) | pSrc[6];
165 low = (low << 8) | pSrc[7];
168 return ((u8) high << 32) | (u8) low;
172 * Grab 2 little-endian bytes and advance the data pointer.
174 INLINE u2 read2LE(unsigned char const** ppSrc)
176 const unsigned char* pSrc = *ppSrc;
178 return pSrc[0] | pSrc[1] << 8;
182 * Grab 4 little-endian bytes and advance the data pointer.
184 INLINE u4 read4LE(unsigned char const** ppSrc)
186 const unsigned char* pSrc = *ppSrc;
190 result |= pSrc[1] << 8;
191 result |= pSrc[2] << 16;
192 result |= pSrc[3] << 24;
199 * Get 8 little-endian bytes and advance the data pointer.
201 INLINE u8 read8LE(unsigned char const** ppSrc)
203 const unsigned char* pSrc = *ppSrc;
208 low |= pSrc[2] << 16;
209 low |= pSrc[3] << 24;
211 high |= pSrc[5] << 8;
212 high |= pSrc[6] << 16;
213 high |= pSrc[7] << 24;
216 return ((u8) high << 32) | (u8) low;
220 * Skip over a UTF-8 string (preceded by a 4-byte length).
222 INLINE void skipUtf8String(unsigned char const** ppSrc)
224 u4 length = read4BE(ppSrc);
230 * Read a UTF-8 string into a fixed-size buffer, and null-terminate it.
232 * Returns the length of the original string.
234 INLINE int readUtf8String(unsigned char const** ppSrc, char* buf, size_t bufLen)
236 u4 length = read4BE(ppSrc);
237 size_t copyLen = (length < bufLen) ? length : bufLen-1;
239 memcpy(buf, *ppSrc, copyLen);
247 * Read a UTF-8 string into newly-allocated storage, and null-terminate it.
249 * Returns the string and its length. (The latter is probably unnecessary
250 * for the way we're using UTF8.)
252 INLINE char* readNewUtf8String(unsigned char const** ppSrc, size_t* pLength)
254 u4 length = read4BE(ppSrc);
257 buf = (char*) malloc(length+1);
259 memcpy(buf, *ppSrc, length);
270 * Set 1 byte. (Included to make code more consistent/legible.)
272 INLINE void set1(u1* buf, u1 val)
278 * Set 2 big-endian bytes.
280 INLINE void set2BE(u1* buf, u2 val)
282 *buf++ = (u1)(val >> 8);
287 * Set 4 big-endian bytes.
289 INLINE void set4BE(u1* buf, u4 val)
291 *buf++ = (u1)(val >> 24);
292 *buf++ = (u1)(val >> 16);
293 *buf++ = (u1)(val >> 8);
298 * Set 8 big-endian bytes.
300 INLINE void set8BE(u1* buf, u8 val)
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);
313 * Set 2 little-endian bytes.
315 INLINE void set2LE(u1* buf, u2 val)
318 *buf = (u1)(val >> 8);
322 * Set 4 little-endian bytes.
324 INLINE void set4LE(u1* buf, u4 val)
327 *buf++ = (u1)(val >> 8);
328 *buf++ = (u1)(val >> 16);
329 *buf = (u1)(val >> 24);
333 * Set 8 little-endian bytes.
335 INLINE void set8LE(u1* buf, u8 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);
348 * Stuff a UTF-8 string into the buffer.
350 INLINE void setUtf8String(u1* buf, const u1* str)
352 u4 strLen = strlen((const char*)str);
355 memcpy(buf + sizeof(u4), str, strLen);
358 #endif // DALVIK_BITS_H_