00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 static const char* TABLE_BYTE_3_B64 ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ ";
00027
00028 static const char* TABLE_BYTE_0_B64 ="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZaaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz0000111122223333444455556666777788889999++++//// ";
00029
00030 # define encodeCHARToBase64(c) (((c)<=25)?(c+'A'):(\
00031 ((c)<=51)?(c+'a'-26):(\
00032 ((c)<=61)?(c+'0'-52):(\
00033 ((c)==61)?'+':'/'))))
00034
00035
00036
00037
00038 bool isBigEndian() {
00039 # define IS_BIG_ENDIAN 2
00040 # define IS_LITTLE_ENDIAN 1
00041 static int checkedEndianess=0;
00042 if (checkedEndianess==0) {
00043 const int i=1;
00044 char *c=(char *)&i;
00045 if (c[sizeof(int)-1]==0) checkedEndianess=IS_LITTLE_ENDIAN;
00046 else checkedEndianess=IS_BIG_ENDIAN;
00047 }
00048 return (checkedEndianess==IS_BIG_ENDIAN);
00049 }
00050
00051
00052
00053
00054 bool isLittleEndian() {
00055 return !isBigEndian();
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 inline void encodeToBase64(unsigned char *in3Bytes, unsigned char *out4Bytes) {
00072 static int i;
00073 if (in3Bytes==NULL || out4Bytes==NULL) return;
00074 *(out4Bytes++)=TABLE_BYTE_0_B64[*in3Bytes];
00075 i= ( *(in3Bytes++)&0x03)<<4;
00076 i|=((*(in3Bytes)&0xf0)>>4);
00077 *(out4Bytes++)=TABLE_BYTE_3_B64[i];
00078 i= ( *(in3Bytes++)&0x0f)<<2;
00079 i|=((*(in3Bytes)&0xc0)>>6);
00080 *(out4Bytes++)=TABLE_BYTE_3_B64[i];
00081 *(out4Bytes++)=TABLE_BYTE_3_B64[*in3Bytes];
00082 }
00083
00084
00085
00086
00087
00088 inline int encodeToBase64(unsigned int n, unsigned char *inBytes, unsigned char *outBytes) {
00089 static unsigned int m;
00090 static unsigned int i, j;
00091 if (inBytes==NULL || outBytes==NULL || n<=0) return 0;
00092 m=n-(n%3);
00093 for ( i=j=0; i<m; i+=3, j+=4) encodeToBase64(inBytes+i,outBytes+j);
00094 if (m!=n) {
00095 char unsigned lastchars[3] = {0,0,0};
00096 lastchars[0]=inBytes[i];
00097 if ((n-m)==2) lastchars[1]=inBytes[i+1];
00098 encodeToBase64(lastchars,outBytes+j);
00099 outBytes[j+3]='=';
00100 if ((n-m)==1) outBytes[j+2]='=';
00101 j+=4;
00102 }
00103 return j;
00104 }
00105
00106
00107
00108
00109
00110 inline int runEncodeToBase64(int n, unsigned char *inBytes, unsigned char *outBytes, bool flushBuffer=false) {
00111 static int cachedChars=0;
00112 static unsigned char charCache[3];
00113 int l=0;
00114
00115
00116 if (cachedChars>0) {
00117
00118 if (n>0) { charCache[cachedChars++]=*inBytes; inBytes++; n--; }
00119 if (cachedChars<3 && n>0) { charCache[cachedChars++]=*inBytes; inBytes++; n--; }
00120
00121 if (cachedChars==3 || flushBuffer) {
00122 l=encodeToBase64(cachedChars,charCache,outBytes);
00123 outBytes+=l;
00124 cachedChars=0;
00125 }
00126 }
00127 if (n==0) return l;
00128
00129 int m=n-n%3;
00130 if (flushBuffer || n==m) {
00131 l+=encodeToBase64(n,inBytes,outBytes);
00132 return l;
00133 }
00134
00135 charCache[cachedChars++]=inBytes[m];
00136 if (m+1<n) charCache[cachedChars++]=inBytes[m+1];
00137 l+=encodeToBase64(m,inBytes,outBytes);
00138 return l;
00139 }
00140
00141
00142
00143
00144
00145 #define flip2Bytes(str) {char c=str[1];str[1]=str[0];str[0]=c;}
00146 #define flip4Bytes(str) {char c=str[3];str[3]=str[0];str[0]=c; c=str[1];str[1]=str[2];str[2]=c;}
00147 #define flip8Bytes(str) {char c=str[7];str[7]=str[0];str[0]=c; \
00148 c=str[6];str[6]=str[1];str[1]=c; \
00149 c=str[5];str[5]=str[2];str[2]=c; \
00150 c=str[4];str[4]=str[3];str[3]=c; }
00151 #define flipNBytes(n,str) {for (int _flip_i=n/2;_flip_i<n;_flip_i++) \
00152 {char c=str[_flip_i];str[_flip_i]=str[n-1-_flip_i];str[n-1-_flip_i]=c;}};
00153
00154 void flipBytes(int size, int n, unsigned char *data) {
00155 if (size==2) for (int i=0; i<n; i++, data+=2) {flip2Bytes(data);}
00156 else if (size==4) for (int i=0; i<n; i++, data+=4) {flip4Bytes(data);}
00157 else if (size==8) for (int i=0; i<n; i++, data+=8) {flip8Bytes(data);}
00158 else for (int i=0; i<n; i++, data+=size) {flipNBytes(size,data);}
00159 }
00160
00161
00162
00163
00164
00165
00166 # define BUFFERED_FWRITE_BUFFER_SIZE 4194304
00167
00168 inline size_t bufferedfwrite(const void *ptr, size_t size, size_t nmemb, std::ostream& stream, bool flush=false) {
00169
00170 static unsigned long idx=0;
00171 static unsigned long ntowrite;
00172 static unsigned long ntocopy;
00173 static unsigned char * buffer=NULL;
00174
00175 if (buffer==NULL) {
00176 buffer=(unsigned char *)malloc(BUFFERED_FWRITE_BUFFER_SIZE);
00177 if (buffer==NULL) {
00178 std::cerr<<"Could not allocate binary write buffer of size " << BUFFERED_FWRITE_BUFFER_SIZE << std::endl;
00179 exit(1);
00180 }
00181 }
00182
00183 if (size==0 || nmemb==0) return 0;
00184
00185 ntowrite=size*nmemb;
00186
00187 if (idx==0 && flush)
00188
00189 return ((stream.write((char *)ptr,ntowrite)).fail()?0:ntowrite);
00190
00191
00192 if (ntowrite>=BUFFERED_FWRITE_BUFFER_SIZE*2) {
00193
00194 stream.write((char *)buffer,idx);
00195
00196 stream.write((char *)ptr,ntowrite);
00197 ntowrite+=idx;
00198 idx=0;
00199 return ntowrite;
00200 }
00201
00202 if (idx+ntowrite>BUFFERED_FWRITE_BUFFER_SIZE)
00203 ntocopy=BUFFERED_FWRITE_BUFFER_SIZE-idx;
00204 else
00205 ntocopy=ntowrite;
00206
00207 memcpy(buffer+idx,ptr,ntocopy);
00208 idx+=ntocopy;
00209
00210 if (flush || idx>=BUFFERED_FWRITE_BUFFER_SIZE) {
00211
00212
00213 stream.write((char *)buffer,idx);
00214
00215 if (ntocopy<ntowrite) {
00216 idx=0;
00217 if (flush)
00218
00219 return ((stream.write((char *)(unsigned char*)(ptr)+ntocopy,ntowrite-ntocopy)).fail()?
00220 0:ntowrite-ntocopy+BUFFERED_FWRITE_BUFFER_SIZE);
00221 idx=ntowrite-ntocopy;
00222 memcpy(buffer,(unsigned char*)(ptr)+ntocopy,idx);
00223 return BUFFERED_FWRITE_BUFFER_SIZE;
00224 }
00225 ntowrite=idx;
00226 idx=0;
00227 return ntowrite;
00228 }
00229 return 0;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238 inline bool encodeToBase64AndWrite(unsigned char *ptr, long n, std::ostream& stream, bool flush=false) {
00239 static unsigned char * buffer=NULL;
00240 static unsigned int nbuffered=0;
00241 static unsigned char * bufferptr=NULL;
00242 static unsigned char * bufferend=NULL;
00243
00244 static unsigned char charsbuffered[4];
00245 static unsigned int ncharsbuffered=0;
00246
00247 static unsigned int v;
00248
00249
00250
00251 if (n==0 && ncharsbuffered==0 && nbuffered==0) return true;
00252
00253 if (buffer==NULL) {
00254 buffer=(unsigned char *)malloc(BUFFERED_FWRITE_BUFFER_SIZE+4);
00255 if (buffer==NULL) {
00256 std::cerr<<"Could not allocate binary write buffer of size " << BUFFERED_FWRITE_BUFFER_SIZE << std::endl;
00257 exit(1);
00258 }
00259 bufferptr=buffer;
00260 bufferend=buffer+BUFFERED_FWRITE_BUFFER_SIZE;
00261 }
00262
00263
00264 if (ncharsbuffered>0 && (n+ncharsbuffered)>2) {
00265 charsbuffered[ncharsbuffered++]=*(ptr++);
00266 n--;
00267 if (ncharsbuffered<3) {
00268 charsbuffered[ncharsbuffered++]=*(ptr++);
00269 n--;
00270 }
00271 encodeToBase64(charsbuffered, bufferptr);
00272 nbuffered+=4;
00273 bufferptr+=4;
00274 ncharsbuffered=0;
00275 }
00276 while (n>2) {
00277 while (n>2 && bufferptr<bufferend) {
00278 *(bufferptr++)=TABLE_BYTE_0_B64[*ptr];
00279 v= ( *(ptr++)&0x03)<<4;
00280 v|=((*(ptr)&0xf0)>>4);
00281 *(bufferptr++)=TABLE_BYTE_3_B64[v];
00282 v= ( *(ptr++)&0x0f)<<2;
00283 v|=((*(ptr)&0xc0)>>6);
00284 *(bufferptr++)=TABLE_BYTE_3_B64[v];
00285 *(bufferptr++)=TABLE_BYTE_3_B64[*(ptr++)];
00286 nbuffered+=4;
00287 n-=3;
00288 }
00289 if (n>0 && n<3) {
00290
00291 if (flush) {
00292 nbuffered+=encodeToBase64(n, ptr, bufferptr);
00293 ptr+=n;
00294 n=0;
00295 } else {
00296 charsbuffered[ncharsbuffered++]=*(ptr++);
00297 n--;
00298 if (n>0) {
00299 charsbuffered[ncharsbuffered++]=*(ptr++);
00300 n--;
00301 }
00302 }
00303
00304 }
00305 if (bufferptr>=bufferend || flush) {
00306 if (stream.write((const char *)buffer,nbuffered).fail()) return false;
00307 bufferptr=buffer;
00308 nbuffered=0;
00309 }
00310 }
00311 if (n>0) {
00312 charsbuffered[ncharsbuffered++]=*(ptr++);
00313 n--;
00314 if (n>0) {
00315 charsbuffered[ncharsbuffered++]=*(ptr++);
00316 n--;
00317 }
00318 }
00319
00320
00321
00322 if (ncharsbuffered>0 && flush) {
00323 nbuffered+=encodeToBase64(ncharsbuffered, charsbuffered, bufferptr);
00324 ncharsbuffered=0;
00325 }
00326 if (bufferptr>=bufferend || flush) {
00327 if (stream.write((const char *)buffer,nbuffered).fail()) return false;
00328 bufferptr=buffer;
00329 nbuffered=0;
00330 }
00331
00332
00333 return true;
00334 }