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