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