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