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 */ 17 INLINE unsigned char get1(unsigned const char* pSrc) 18 { 19 return *pSrc; 20 } 21 22 /* 23 * Get 2 big-endian bytes. 24 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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