00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00090 #ifndef _basex_h
00091 #define _basex_h
00092
00093 #include "compiler_opt.h"
00094
00095
00096 #ifndef NO_BASE16_LOOKUP_TABLE
00097 #define BASE16_LOOKUP_TABLE
00098 #endif
00099
00100 #ifndef NO_BASE64_LOOKUP_TABLE
00101 #define BASE64_LOOKUP_TABLE
00102 #endif
00103
00104 #ifndef NO_BASE64_LOOKUP_8K
00105 #define BASE64_LOOKUP_8K
00106 #endif
00107
00108 #ifndef NO_BASE16_LOOKUP_LARGE
00109 #define BASE16_LOOKUP_LARGE
00110 #endif
00111
00112 #if !defined NO_BASE64_LOOKUP_LARGE && !defined BASE64_LOOKUP_8K
00113 #define BASE64_LOOKUP_LARGE
00114 #endif
00115
00116
00117
00118 #if defined BASE16_READ_WHOLE_INTS || defined BASE64_READ_WHOLE_INTS || \
00119 defined BASE64_LOOKUP_8K
00120 #include "endianness.h"
00121
00123 #define ALIGN_POINTER(p, type) \
00124 ((type*) ((long)((char*)(p)+sizeof(type)-1)&~(long)(sizeof(type)-1)))
00125
00126 #define ALIGN_UINT_POINTER(p) ALIGN_POINTER(p, unsigned int)
00127
00128 #endif
00129
00130
00131 #ifdef BASE16_LOOKUP_TABLE
00132
00133 #ifdef BASE16_LOOKUP_LARGE
00134
00136 extern unsigned char _bx_hexdig_hi[256];
00137 extern unsigned char _bx_hexdig_low[256];
00138
00140 #define HEX_HI(h) _bx_hexdig_hi[(unsigned char)(h)]
00141
00142 #define HEX_LOW(h) _bx_hexdig_low[(unsigned char)(h)]
00143
00144 extern unsigned char _bx_unhexdig256[256];
00145
00150 #define UNHEX(h) _bx_unhexdig256[(h)]
00151
00152 #else
00153
00155 extern unsigned char _bx_hexdig[16+1];
00156
00157 #define HEX_4BITS(h) _bx_hexdig[(h)]
00158 #define HEX_HI(h) HEX_4BITS(((unsigned char)(h))>>4)
00159 #define HEX_LOW(h) HEX_4BITS((h)&0xf)
00160
00161 extern unsigned char _bx_unhexdig32[32];
00162 #define UNHEX(h) _bx_unhexdig32[(((h))-'0')&0x1f]
00163
00164 #endif
00165
00166 #else
00167
00168 #if 0
00169 #define HEX_4BITS(h) (unsigned char)((unlikely((h)>=10))?((h)-10+'A'):(h)+'0')
00170 #define UNHEX(c) (unsigned char)((unlikely((c)>='A'))?(c)-'A'+10:(c)-'0')
00171 #else
00172 #define HEX_4BITS(hc) (unsigned char)( ((((hc)>=10)-1)&((hc)+'0')) | \
00173 ((((hc)<10)-1)&((hc)+'A')) )
00174 #define UNHEX(c) (unsigned char) ( ((((c)>'9')-1)& ((c)-'0')) | \
00175 ((((c)<='9')-1)&((c)-'A')) )
00176 #endif
00177
00178 #define HEX_HI(h) HEX_4BITS(((unsigned char)(h))>>4)
00179 #define HEX_LOW(h) HEX_4BITS((h)&0xf)
00180
00181 #endif
00182
00183
00184 #ifdef BASE64_LOOKUP_TABLE
00185 #ifdef BASE64_LOOKUP_LARGE
00186
00187
00188 extern unsigned char _bx_b64_first[256];
00189 extern unsigned char _bx_b64_second[4][256];
00190 extern unsigned char _bx_b64_third[4][256];
00191 extern unsigned char _bx_b64_fourth[256];
00192
00193 #define BASE64_1(a) _bx_b64_first[(a)]
00194 #define BASE64_2(a,b) _bx_b64_second[(a)&0x3][(b)]
00195 #define BASE64_3(b,c) _bx_b64_third[(c)>>6][(b)]
00196 #define BASE64_4(c) _bx_b64_fourth[(c)]
00197
00198 extern unsigned char _bx_ub64[256];
00199 #define UNBASE64(v) _bx_ub64[(v)]
00200
00201 #elif defined BASE64_LOOKUP_8K
00202
00203 extern unsigned short _bx_b64_12[4096];
00204
00205
00206 #define BASE64_12(a,b) _bx_b64_12[((a)<<4)|((b)>>4)]
00207 #define BASE64_34(b,c) _bx_b64_12[(((b)&0xf)<<8)|(c)]
00208 #ifdef __IS_LITTLE_ENDIAN
00209 #define FIRST_8B(s) ((unsigned char)(s))
00210 #define LAST_8B(s) ((s)>>8)
00211 #elif defined __IS_BIG_ENDIAN
00212 #define FIRST_8B(s) ((s)>>8)
00213 #define LAST_8B(s) ((unsigned char)(s))
00214 #else
00215 #error neither __IS_LITTLE_ENDIAN nor __IS_BIG_ENDIAN are defined
00216 #endif
00217
00218
00219 extern unsigned char _bx_ub64[256];
00220 #define UNBASE64(v) _bx_ub64[(v)]
00221
00222 #else
00223
00224 extern unsigned char _bx_b64[64+1];
00225
00226 #define BASE64_DIG(v) _bx_b64[(v)]
00227
00228 #define BASE64_1(a) BASE64_DIG((a)>>2)
00229 #define BASE64_2(a, b) BASE64_DIG( (((a)<<4)&0x3f) | ((b)>>4))
00230 #define BASE64_3(b, c) BASE64_DIG( (((b)<<2)&0x3f) | ((c)>>6))
00231 #define BASE64_4(c) BASE64_DIG((c)&0x3f)
00232
00233 extern unsigned char _bx_ub64[0x54+1];
00234 #define UNBASE64(v) _bx_ub64[(((v)&0x7f)-0x2b)]
00235
00236 #endif
00237
00238
00239 #else
00240
00241 #define BASE64_DIG(v) base64_enc_char(v)
00242 #define BASE64_1(a) BASE64_DIG((a)>>2)
00243 #define BASE64_2(a, b) BASE64_DIG( (((a)<<4)&0x3f) | ((b)>>4))
00244 #define BASE64_3(b, c) BASE64_DIG( (((b)<<2)&0x3f) | ((c)>>6))
00245 #define BASE64_4(c) BASE64_DIG((c)&0x3f)
00246
00247 #define UNBASE64(v) base64_dec_char(v)
00248
00249 #endif
00250
00251
00252
00254 #define base16_enc_len(l) (l*2)
00255
00256 #define base16_max_dec_len(l) (l/2)
00257
00258 #define base16_dec_len(b, l) base16_max_dec_len(l)
00259
00260 #define base16_dec_min_len() 2
00261
00262 #define base16_enc_min_len() 0
00263
00265 #define base64_enc_len(l) (((l)+2)/3*4)
00266
00267 #define base64_max_dec_len(l) ((l)/4*3)
00268
00269 #define base64_dec_len(b, l) \
00270 (base64_max_dec_len(l)-((b)[(l)-2]=='=') -((b)[(l)-1]=='='))
00271
00272 #define base64_dec_min_len() 4
00273
00274 #define base64_enc_min_len() 0
00275
00276
00277 #ifdef BASE16_READ_WHOLE_INTS
00278
00286 inline static int base16_enc(unsigned char* src, int slen, unsigned char* dst, int dlen)
00287 {
00288 unsigned int* p;
00289 unsigned char* end;
00290 int osize;
00291 unsigned short us;
00292
00293 osize=2*slen;
00294 if (unlikely(dlen<osize))
00295 return -osize;
00296 end=src+slen;
00297 p=ALIGN_UINT_POINTER(src);
00298 if (likely((unsigned char*)p<end)){
00299 switch((unsigned char)((unsigned char*)p-src)){
00300 case 3:
00301 *dst=HEX_HI(*src);
00302 *(dst+1)=HEX_LOW(*src);
00303 dst+=2;
00304 src++;
00305
00306 case 2:
00307 us=*(unsigned short*)(src);
00308 #if defined __IS_LITTLE_ENDIAN
00309 *(dst+0)=HEX_HI(us);
00310 *(dst+1)=HEX_LOW(us);
00311 *(dst+2)=HEX_HI(us>>8);
00312 *(dst+3)=HEX_LOW(us>>8);
00313 #elif defined __IS_BIG_ENDIAN
00314 *(dst+2)=HEX_HI(us);
00315 *(dst+3)=HEX_LOW(us);
00316 *(dst+0)=HEX_HI(us>>8);
00317 *(dst+1)=HEX_LOW(us>>8);
00318 #endif
00319 dst+=4;
00320
00321 break;
00322 case 1:
00323 *dst=HEX_HI(*src);
00324 *(dst+1)=HEX_LOW(*src);
00325 dst+=2;
00326
00327 case 0:
00328 break;
00329 }
00330 for(;(unsigned char*)p<=(end-4);p++,dst+=8){
00331 #if defined __IS_LITTLE_ENDIAN
00332 *(dst+0)=HEX_HI(*p);
00333 *(dst+1)=HEX_LOW(*p);
00334 *(dst+2)=HEX_HI(((*p)>>8));
00335 *(dst+3)=HEX_LOW(((*p)>>8));
00336 *(dst+4)=HEX_HI(((*p)>>16));
00337 *(dst+5)=HEX_LOW(((*p)>>16));
00338 *(dst+6)=HEX_HI(((*p)>>24));
00339 *(dst+7)=HEX_LOW(((*p)>>24));
00340 #elif defined __IS_BIG_ENDIAN
00341 *(dst+6)=HEX_HI(*p);
00342 *(dst+7)=HEX_LOW(*p);
00343 *(dst+4)=HEX_HI(((*p)>>8));
00344 *(dst+5)=HEX_LOW(((*p)>>8));
00345 *(dst+2)=HEX_HI(((*p)>>16));
00346 *(dst+3)=HEX_LOW(((*p)>>16));
00347 *(dst+0)=HEX_HI(((*p)>>24));
00348 *(dst+1)=HEX_LOW(((*p)>>24));
00349 #else
00350 #error neither BIG ro LITTLE endian defined
00351 #endif
00352 }
00353 src=(unsigned char*)p;
00354
00355 switch((unsigned char)((unsigned char*)end-src)){
00356 case 3:
00357 case 2:
00358 us=*(unsigned short*)(src);
00359 #if defined __IS_LITTLE_ENDIAN
00360 *(dst+0)=HEX_HI(us);
00361 *(dst+1)=HEX_LOW(us);
00362 *(dst+2)=HEX_HI(us>>8);
00363 *(dst+3)=HEX_LOW(us>>8);
00364 #elif defined __IS_BIG_ENDIAN
00365 *(dst+2)=HEX_HI(us);
00366 *(dst+3)=HEX_LOW(us);
00367 *(dst+0)=HEX_HI(us>>8);
00368 *(dst+1)=HEX_LOW(us>>8);
00369 #endif
00370 if ((end-src)==3){
00371 *(dst+4)=HEX_HI(*(src+2));
00372 *(dst+5)=HEX_LOW(*(src+2));
00373 }
00374
00375 break;
00376 case 1:
00377 *dst=HEX_HI(*src);
00378 *(dst+1)=HEX_LOW(*src);
00379
00380 case 0:
00381 break;
00382 }
00383 }else if (unlikely((long)src&1)){
00384
00385 switch((unsigned char)((unsigned char*)end-src)){
00386 case 3:
00387 *dst=HEX_HI(*src);
00388 *(dst+1)=HEX_LOW(*src);
00389 dst+=2;
00390 src++;
00391
00392 case 2:
00393 us=*(unsigned short*)(src);
00394 #if defined __IS_LITTLE_ENDIAN
00395 *(dst+0)=HEX_HI(us);
00396 *(dst+1)=HEX_LOW(us);
00397 *(dst+2)=HEX_HI(us>>8);
00398 *(dst+3)=HEX_LOW(us>>8);
00399 #elif defined __IS_BIG_ENDIAN
00400 *(dst+2)=HEX_HI(us);
00401 *(dst+3)=HEX_LOW(us);
00402 *(dst+0)=HEX_HI(us>>8);
00403 *(dst+1)=HEX_LOW(us>>8);
00404 #endif
00405
00406 break;
00407 case 1:
00408 *dst=HEX_HI(*src);
00409 *(dst+1)=HEX_LOW(*src);
00410
00411 case 0:
00412 break;
00413 }
00414 }else{
00415
00416 switch((unsigned char)((unsigned char*)end-src)){
00417 case 3:
00418 case 2:
00419 us=*(unsigned short*)(src);
00420 #if defined __IS_LITTLE_ENDIAN
00421 *(dst+0)=HEX_HI(us);
00422 *(dst+1)=HEX_LOW(us);
00423 *(dst+2)=HEX_HI(us>>8);
00424 *(dst+3)=HEX_LOW(us>>8);
00425 #elif defined __IS_BIG_ENDIAN
00426 *(dst+2)=HEX_HI(us);
00427 *(dst+3)=HEX_LOW(us);
00428 *(dst+0)=HEX_HI(us>>8);
00429 *(dst+1)=HEX_LOW(us>>8);
00430 #endif
00431 if ((end-src)==3){
00432 *(dst+4)=HEX_HI(*(src+2));
00433 *(dst+5)=HEX_LOW(*(src+2));
00434 }
00435
00436 break;
00437 case 1:
00438 *dst=HEX_HI(*src);
00439 *(dst+1)=HEX_LOW(*src);
00440
00441 case 0:
00442 break;
00443 }
00444 }
00445
00446 return osize;
00447 }
00448
00449
00450
00451 #else
00452
00453
00460 inline static int base16_enc(unsigned char* src, int slen,
00461 unsigned char* dst, int dlen)
00462 {
00463 unsigned char* end;
00464 int osize;
00465
00466 osize=2*slen;
00467 if (unlikely(dlen<osize))
00468 return -osize;
00469 end=src+slen;
00470 for (;src<end; src++,dst+=2){
00471 *dst=HEX_HI(*src);
00472 *(dst+1)=HEX_LOW(*src);
00473 }
00474 return osize;
00475 }
00476
00477
00478 #endif
00479
00480 inline static int base16_dec(unsigned char* src, int slen, unsigned char* dst, int dlen)
00481 {
00482 unsigned char* end;
00483 int osize;
00484
00485 osize=slen/2;
00486 if (unlikely(dlen<osize))
00487 return -osize;
00488 end=src+2*osize;
00489 for (; src<end; src+=2, dst++)
00490 *dst=(UNHEX(*src)<<4) | UNHEX(*(src+1));
00491 return osize;
00492 }
00493
00494
00495
00496
00497
00501 inline static unsigned char base64_enc_char(unsigned char v)
00502 {
00503 switch(v){
00504 case 0x3f:
00505 return '/';
00506 case 0x3e:
00507 return '+';
00508 default:
00509 if (v<=25)
00510 return v+'A';
00511 else if (v<=51)
00512 return v-26+'a';
00513 else if (v<=61)
00514 return v-52+'0';
00515 }
00516 return 0xff;
00517 }
00518
00521 inline static unsigned base64_dec_char(unsigned char v)
00522 {
00523 switch(v){
00524 case '/':
00525 return 0x3f;
00526 case '+':
00527 return 0x3e;
00528 case ':':
00529 case ';':
00530 case '<':
00531 case '=':
00532 case '>':
00533 case '?':
00534 case '@':
00535 case '[':
00536 case '\\':
00537 case ']':
00538 case '^':
00539 case '_':
00540 case '`':
00541 return 0xff;
00542 default:
00543 if ((v)<'0')
00544 return 0xff;
00545 if ((v)<='9')
00546 return (v)-'0'+0x34;
00547 else if ((v)<='Z')
00548 return (v)-'A';
00549 else if ((v) <='z')
00550 return (v)-'a'+0x1a;
00551 }
00552 return 0xff;
00553 }
00554
00555
00556 #ifdef BASE64_LOOKUP_8K
00557
00563 inline static int base64_enc(unsigned char* src, int slen,
00564 unsigned char* dst, int dlen)
00565 {
00566 unsigned char* end;
00567 int osize;
00568
00569 osize=(slen+2)/3*4;
00570 if (unlikely(dlen<osize))
00571 return -osize;
00572 end=src+slen/3*3;
00573 if (unlikely((long)dst%2)){
00574 for (;src<end; src+=3,dst+=4){
00575 dst[0]=FIRST_8B(BASE64_12(src[0], src[1]));
00576 dst[1]=LAST_8B(BASE64_12(src[0], src[1]));
00577 dst[2]=FIRST_8B(BASE64_34(src[1], src[2]));
00578 dst[3]=LAST_8B(BASE64_34(src[1], src[2]));
00579 }
00580 switch(slen%3){
00581 case 2:
00582 dst[0]=FIRST_8B(BASE64_12(src[0], src[1]));
00583 dst[1]=LAST_8B(BASE64_12(src[0], src[1]));
00584 dst[2]=FIRST_8B(BASE64_34(src[1], 0));
00585 dst[3]='=';
00586 break;
00587 case 1:
00588 dst[0]=FIRST_8B(BASE64_12(src[0], 0));
00589 dst[1]=LAST_8B(BASE64_12(src[0], 0));
00590 dst[2]='=';
00591 dst[3]='=';
00592 break;
00593 }
00594 }else{
00595 for (;src<end; src+=3,dst+=4){
00596 *(unsigned short*)(dst+0)=_bx_b64_12[(src[0]<<4)|(src[1]>>4)];
00597 *(unsigned short*)(dst+2)=_bx_b64_12[((src[1]&0xf)<<8)|src[2]];
00598 }
00599 switch(slen%3){
00600 case 2:
00601 *(unsigned short*)(dst+0)=_bx_b64_12[(src[0]<<4)|(src[1]>>4)];
00602 *(unsigned short*)(dst+2)=_bx_b64_12[((src[1]&0xf)<<8)|0];
00603 dst[3]='=';
00604 break;
00605 case 1:
00606 *(unsigned short*)(dst+0)=_bx_b64_12[(src[0]<<4)|0];
00607 dst[2]='=';
00608 dst[3]='=';
00609 break;
00610 }
00611 }
00612 return osize;
00613 }
00614 #else
00615
00620 inline static int base64_enc(unsigned char* src, int slen,
00621 unsigned char* dst, int dlen)
00622 {
00623 unsigned char* end;
00624 int osize;
00625
00626 osize=(slen+2)/3*4;
00627 if (unlikely(dlen<osize))
00628 return -osize;
00629 end=src+slen/3*3;
00630 for (;src<end; src+=3,dst+=4){
00631 dst[0]=BASE64_1(src[0]);
00632 dst[1]=BASE64_2(src[0], src[1]);
00633 dst[2]=BASE64_3(src[1], src[2]);
00634 dst[3]=BASE64_4(src[2]);
00635 }
00636 switch(slen%3){
00637 case 2:
00638 dst[0]=BASE64_1(src[0]);
00639 dst[1]=BASE64_2(src[0], src[1]);
00640 dst[2]=BASE64_3(src[1], 0);
00641 dst[3]='=';
00642 break;
00643 case 1:
00644 dst[0]=BASE64_1(src[0]);
00645 dst[1]=BASE64_2(src[0], 0);
00646 dst[2]='=';
00647 dst[3]='=';
00648 break;
00649 }
00650 return osize;
00651 }
00652 #endif
00653
00654
00655
00661 inline static int base64_dec(unsigned char* src, int slen,
00662 unsigned char* dst, int dlen)
00663 {
00664
00665 unsigned char* end;
00666 int osize;
00667 register unsigned a, b, c, d;
00668
00669
00670 if (unlikely((slen<4) || (slen%4) ||
00671 (src[slen-2]=='=' && src[slen-1]!='=')))
00672 return 0;
00673 osize=(slen/4*3)-(src[slen-2]=='=')-(src[slen-1]=='=');
00674 if (unlikely(dlen<osize))
00675 return -osize;
00676 end=src+slen-4;
00677 for (;src<end; src+=4,dst+=3){
00678 #if 0
00679 u= (UNBASE64(src[0])<<18) | (UNBASE64(src[1])<<12) |
00680 (UNBASE64(src[2])<<6) | UNBASE64(src[3]);
00681 dst[0]=u>>16;
00682 dst[1]=u>>8;
00683 dst[3]=u;
00684 #endif
00685 a=UNBASE64(src[0]);
00686 b=UNBASE64(src[1]);
00687 c=UNBASE64(src[2]);
00688 d=UNBASE64(src[3]);
00689 dst[0]=(a<<2) | (b>>4);
00690 dst[1]=(b<<4) | (c>>2);
00691 dst[2]=(c<<6) | d;
00692 }
00693 switch(osize%3){
00694 case 0:
00695 a=UNBASE64(src[0]);
00696 b=UNBASE64(src[1]);
00697 c=UNBASE64(src[2]);
00698 d=UNBASE64(src[3]);
00699 dst[0]=(a<<2) | (b>>4);
00700 dst[1]=(b<<4) | (c>>2);
00701 dst[2]=(c<<6) | d;
00702 break;
00703 case 2:
00704 a=UNBASE64(src[0]);
00705 b=UNBASE64(src[1]);
00706 c=UNBASE64(src[2]);
00707 dst[0]=(a<<2) | (b>>4);
00708 dst[1]=(b<<4) | (c>>2);
00709 break;
00710 case 1:
00711 a=UNBASE64(src[0]);
00712 b=UNBASE64(src[1]);
00713 dst[0]=(a<<2) | (b>>4);
00714 break;
00715 }
00716 return osize;
00717 }
00718
00719
00720
00721
00730 inline static int q_base64_enc(unsigned char* src, int slen,
00731 unsigned char* dst, int dlen)
00732 {
00733 #define q_b64_base '0'
00734 #define q_b64_pad 'z'
00735 #define Q_BASE64(v) (unsigned char)((v)+q_b64_base)
00736 unsigned char* end;
00737 int osize;
00738
00739 osize=(slen+2)/3*4;
00740 if (unlikely(dlen<osize))
00741 return -osize;
00742 end=src+slen/3*3;
00743 for (;src<end; src+=3,dst+=4){
00744 dst[0]=Q_BASE64(src[0]>>2);
00745 dst[1]=(Q_BASE64((src[0]<<4)&0x3f) | (src[1]>>4));
00746 dst[2]=(Q_BASE64((src[1]<<2)&0x3f) | (src[2]>>6) );
00747 dst[3]=Q_BASE64(src[2]&0x3f);
00748 }
00749 switch(slen%3){
00750 case 2:
00751 dst[0]=Q_BASE64(src[0]>>2);
00752 dst[1]=(Q_BASE64((src[0]<<4)&0x3f) | (src[1]>>4));
00753 dst[2]=Q_BASE64((src[1]<<2)&0x3f);
00754 dst[3]=q_b64_pad;
00755 break;
00756 case 1:
00757 dst[0]=Q_BASE64(src[0]>>2);
00758 dst[1]=Q_BASE64((src[0]<<4)&0x3f);
00759 dst[2]=q_b64_pad;
00760 dst[3]=q_b64_pad;
00761 break;
00762 }
00763 return osize;
00764 #undef Q_BASE64
00765 }
00766
00767
00768
00777 inline static int q_base64_dec(unsigned char* src, int slen,
00778 unsigned char* dst, int dlen)
00779 {
00780 #define Q_UNBASE64(v) (unsigned char)((v)-q_b64_base)
00781
00782 unsigned char* end;
00783 int osize;
00784 #ifdef SINGLE_REG
00785 register unsigned u;
00786 #else
00787 register unsigned a, b, c, d;
00788
00789 #endif
00790
00791 if (unlikely((slen<4) || (slen%4) ||
00792 (src[slen-2]==q_b64_pad && src[slen-1]!=q_b64_pad)))
00793 return 0;
00794 osize=(slen/4*3)-(src[slen-2]==q_b64_pad)-(src[slen-1]==q_b64_pad);
00795 if (unlikely(dlen<osize))
00796 return -osize;
00797 end=src+slen-4;
00798 for (;src<end; src+=4,dst+=3){
00799 #ifdef SINGLE_REG
00800 u= (Q_UNBASE64(src[0])<<18) | (Q_UNBASE64(src[1])<<12) |
00801 (Q_UNBASE64(src[2])<<6) | Q_UNBASE64(src[3]);
00802 dst[0]=u>>16;
00803 dst[1]=u>>8;
00804 dst[2]=u;
00805 #else
00806 a=Q_UNBASE64(src[0]);
00807 b=Q_UNBASE64(src[1]);
00808 c=Q_UNBASE64(src[2]);
00809 d=Q_UNBASE64(src[3]);
00810 dst[0]=(a<<2) | (b>>4);
00811 dst[1]=(b<<4) | (c>>2);
00812 dst[2]=(c<<6) | d;
00813 #endif
00814 }
00815 switch(osize%3){
00816 case 0:
00817 #ifdef SINGLE_REG
00818 u= (Q_UNBASE64(src[0])<<18) | (Q_UNBASE64(src[1])<<12) |
00819 (Q_UNBASE64(src[2])<<6) | Q_UNBASE64(src[3]);
00820 dst[0]=u>>16;
00821 dst[1]=u>>8;
00822 dst[2]=u;
00823 #else
00824 a=Q_UNBASE64(src[0]);
00825 b=Q_UNBASE64(src[1]);
00826 c=Q_UNBASE64(src[2]);
00827 d=Q_UNBASE64(src[3]);
00828 dst[0]=(a<<2) | (b>>4);
00829 dst[1]=(b<<4) | (c>>2);
00830 dst[2]=(c<<6) | d;
00831 #endif
00832 break;
00833 case 2:
00834 #ifdef SINGLE_REG
00835 u= (Q_UNBASE64(src[0])<<12) | (Q_UNBASE64(src[1])<<6) |
00836 (Q_UNBASE64(src[2]));
00837 dst[0]=u>>10;
00838 dst[1]=u>>2;
00839 #else
00840 a=Q_UNBASE64(src[0]);
00841 b=Q_UNBASE64(src[1]);
00842 c=Q_UNBASE64(src[2]);
00843 dst[0]=(a<<2) | (b>>4);
00844 dst[1]=(b<<4) | (c>>2);
00845 #endif
00846 break;
00847 case 1:
00848 #ifdef SINGLE_REG
00849 dst[0]=(Q_UNBASE64(src[0])<<2) | (Q_UNBASE64(src[1])>>4);
00850 #else
00851 a=Q_UNBASE64(src[0]);
00852 b=Q_UNBASE64(src[1]);
00853 dst[0]=(a<<2) | (b>>4);
00854 #endif
00855 break;
00856 }
00857 return osize;
00858 #undef q_b64_base
00859 #undef q_b64_pad
00860 }
00861
00863 int init_basex(void);
00864
00865
00866 #endif