75a76
> #include <ctype.h>
90a92,111
> 
> // the base64 alphabet according to definition in RFC 2045
> const XMLCh Base64::base64Alphabet[64] = {
>     chLatin_A, chLatin_B, chLatin_C, chLatin_D, chLatin_E,
>     chLatin_F, chLatin_G, chLatin_H, chLatin_I, chLatin_J,
>     chLatin_K, chLatin_L, chLatin_M, chLatin_N, chLatin_O,
>     chLatin_P, chLatin_Q, chLatin_R, chLatin_S, chLatin_T,
>     chLatin_U, chLatin_V, chLatin_W, chLatin_X, chLatin_Y,
>     chLatin_Z, chLatin_a, chLatin_b, chLatin_c, chLatin_d,
>     chLatin_e, chLatin_f, chLatin_g, chLatin_h, chLatin_i,
>     chLatin_j, chLatin_k, chLatin_l, chLatin_m, chLatin_n,
>     chLatin_o, chLatin_p, chLatin_q, chLatin_r, chLatin_s,
>     chLatin_t, chLatin_u, chLatin_v, chLatin_w, chLatin_x,
>     chLatin_y, chLatin_z, chDigit_0, chDigit_1, chDigit_2,
>     chDigit_3, chDigit_4, chDigit_5, chDigit_6, chDigit_7,
>     chDigit_8, chDigit_9, chPlus, chForwardSlash
> };
> const XMLCh Base64::base64Padding = chEqual;
> 
> XMLCh Base64::base64Inverse[ BASELENGTH ];
92c113,212
< XMLCh Base64::base64Alphabet[BASELENGTH]; 
---
> 
> // number of quadruplets per one line ( must be >1 and <19 )
> const unsigned int Base64::quadsPerLine = 15;
> 
> XMLCh* Base64::encode( 
>     const XMLCh* const inputData,
>     const int inputLength,
>     int *outputLength )
> {
>     if (!isInitialized)
>         init();
> 
>     if ( inputData == 0 )
>         return 0;
> 
>     int quadrupletCount = ( inputLength + 2 ) / 3;
>     if (quadrupletCount == 0)
>         return 0;
> 
>     // number of rows in encoded stream ( including the last one )
>     int lineCount = ( quadrupletCount + quadsPerLine-1 ) / quadsPerLine;
> 
>     //
>     // convert the triplet(s) to quadruplet(s)
>     //
>     XMLCh  b1, b2, b3, b4;  // base64 binary codes ( 0..63 )
> 
>     int inputIndex = 0;
>     int outputIndex = 0;
>     XMLCh *encodedData = 
>         new XMLCh[ quadrupletCount*FOURBYTE + lineCount + 1 ];
> 
>     //
>     // Process all quadruplet(s) except the last
>     //
>     int quad = 1;
>     for (; quad <= quadrupletCount-1; quad++ )
>     {
>         // read triplet from the input stream
>         split1stOctet( inputData[ inputIndex++ ], b1, b2 );
>         split2ndOctet( inputData[ inputIndex++ ], b2, b3 );
>         split3rdOctet( inputData[ inputIndex++ ], b3, b4 );
> 
>         // write quadruplet to the output stream
>         encodedData[ outputIndex++ ] = base64Alphabet[ b1 ];
>         encodedData[ outputIndex++ ] = base64Alphabet[ b2 ];
>         encodedData[ outputIndex++ ] = base64Alphabet[ b3 ];
>         encodedData[ outputIndex++ ] = base64Alphabet[ b4 ];
> 
>         if (( quad % quadsPerLine ) == 0 )
>             encodedData[ outputIndex++ ] = chLF;
>     }
> 
>     //
>     // process the last Quadruplet
>     //
>     // first octet is present always, process it
>     split1stOctet( inputData[ inputIndex++ ], b1, b2 );
>     encodedData[ outputIndex++ ] = base64Alphabet[ b1 ];
> 
>     if( inputIndex < inputLength )
>     {
>         // second octet is present, process it
>         split2ndOctet( inputData[ inputIndex++ ], b2, b3 );
>         encodedData[ outputIndex++ ] = base64Alphabet[ b2 ];
> 
>         if( inputIndex < inputLength )
>         {
>             // third octet present, process it
>             // no PAD e.g. 3cQl
>             split3rdOctet( inputData[ inputIndex++ ], b3, b4 );
>             encodedData[ outputIndex++ ] = base64Alphabet[ b3 ];
>             encodedData[ outputIndex++ ] = base64Alphabet[ b4 ];
>         }
>         else
>         {
>             // third octet not present
>             // one PAD e.g. 3cQ=
>             encodedData[ outputIndex++ ] = base64Alphabet[ b3 ];
>             encodedData[ outputIndex++ ] = base64Padding;
>         }
>     }
>     else
>     {
>         // second octet not present
>         // two PADs e.g. 3c==
>         encodedData[ outputIndex++ ] = base64Padding;
>         encodedData[ outputIndex++ ] = base64Padding;
>     }
> 
>     // write out end of the last line
>     encodedData[ outputIndex++ ] = chLF;
>     // write out end of string
>     encodedData[ outputIndex ] = 0;
> 
>     if( outputLength != 0 )
>       (*outputLength) = outputIndex;
> 
>     return encodedData;
> }
107c227
< int Base64::getDataLength(const XMLCh* const base64Data)
---
> int Base64::getDataLength( const XMLCh* const inputData )
110c230
<     XMLCh* decodedData = decode(base64Data, retLen);
---
>     XMLCh* decodedData = decode( inputData, retLen );
127c247
< // temporary data, normalizedBase64Data, is ALWAYS released by this function.
---
> // temporary data, rawInputData, is ALWAYS released by this function.
129c249
< XMLCh* Base64::decode(const XMLCh* const base64Data, int& base64DataLen)
---
> XMLCh* Base64::decode( const XMLCh* const inputData, int& outputLength )
134c254
<     if (( base64Data == 0 ) || ( *base64Data == 0 ))
---
>     if (( inputData == 0 ) || ( *inputData == 0 ))
138c258
<     // remove whitespaces from the base64Data
---
>     // remove all whitespaces from the base64Data
140,142c260,269
<     XMLCh* normalizedBase64Data = XMLString::replicate(base64Data);
<     XMLString::trim(normalizedBase64Data);
<     ArrayJanitor<XMLCh> jan(normalizedBase64Data);
---
>     int inputLength = XMLString::stringLen( inputData );
>     XMLCh* rawInputData = new XMLCh[ inputLength + 1 ];
>     ArrayJanitor<XMLCh> jan(rawInputData);
> 
>     int inputIndex = 0;
>     int rawInputLength = 0;
>     while ( inputIndex < inputLength )
>     {
>         if( !isspace( inputData[ inputIndex ] ))
>             rawInputData[ rawInputLength++ ] = inputData[ inputIndex ];
144,148c271,276
<     //
<     // check the length: should be divisible by four
<     //
<     int strLen = XMLString::stringLen(normalizedBase64Data);
<     if (strLen%FOURBYTE != 0) 
---
>         inputIndex++;
>     }
>     rawInputData[ rawInputLength ] = 0;
> 
>     // the length of raw data should be divisible by four
>     if (( rawInputLength % FOURBYTE ) != 0 ) 
151,152c279,280
<     int numberQuadruple = strLen/FOURBYTE;
<     if (numberQuadruple == 0)
---
>     int quadrupletCount = rawInputLength / FOURBYTE;
>     if ( quadrupletCount == 0 )
158,159c286,287
<     XMLCh    d1, d2, d3, d4;
<     XMLCh    b1, b2, b3, b4;
---
>     XMLCh  d1, d2, d3, d4;  // base64 characters
>     XMLCh  b1, b2, b3, b4;  // base64 binary codes ( 0..64 )
161,164c289,291
<     int i = 0;
<     int encodedIndex = 0;
<     int dataIndex    = 0;
<     XMLCh  *decodedData = new XMLCh[numberQuadruple*3+1];
---
>     int rawInputIndex  = 0;
>     int outputIndex    = 0;
>     XMLCh *decodedData = new XMLCh[ quadrupletCount*3 + 1 ];
167c294
<     // Prcess all quadruple(s) except for the last
---
>     // Process all quadruplet(s) except the last
169c296,297
<     for (; i < numberQuadruple-1; i++) 
---
>     int quad = 1;
>     for (; quad <= quadrupletCount-1; quad++ )
171,174c299,303
<         if  (!isData( (d1 = normalizedBase64Data[dataIndex++]) )||  
<              !isData( (d2 = normalizedBase64Data[dataIndex++]) )||
<              !isData( (d3 = normalizedBase64Data[dataIndex++]) )||
<              !isData( (d4 = normalizedBase64Data[dataIndex++]) ))
---
>         // read quadruplet from the input stream
>         if (!isData( (d1 = rawInputData[ rawInputIndex++ ]) ) ||
>             !isData( (d2 = rawInputData[ rawInputIndex++ ]) ) ||
>             !isData( (d3 = rawInputData[ rawInputIndex++ ]) ) ||
>             !isData( (d4 = rawInputData[ rawInputIndex++ ]) ))
175a305
>             // if found "no data" just return NULL
177c307
<             return 0;//if found "no data" just return null
---
>             return 0;
180,187c310,318
<         b1 = base64Alphabet[d1]; 
<         b2 = base64Alphabet[d2];
<         b3 = base64Alphabet[d3];
<         b4 = base64Alphabet[d4];
< 
<         decodedData[encodedIndex++] = set1stOctect(b1, b2);
<         decodedData[encodedIndex++] = set2ndOctect(b2, b3);
<         decodedData[encodedIndex++] = set3rdOctect(b3, b4);
---
>         b1 = base64Inverse[ d1 ];
>         b2 = base64Inverse[ d2 ];
>         b3 = base64Inverse[ d3 ];
>         b4 = base64Inverse[ d4 ];
> 
>         // write triplet to the output stream
>         decodedData[ outputIndex++ ] = set1stOctet(b1, b2);
>         decodedData[ outputIndex++ ] = set2ndOctet(b2, b3);
>         decodedData[ outputIndex++ ] = set3rdOctet(b3, b4);
191,194c322,326
<     // process the last Quadruple
<     // the first two octets
<     if (!isData( (d1 = normalizedBase64Data[dataIndex++]) ) ||  
<         !isData( (d2 = normalizedBase64Data[dataIndex++]) )) 
---
>     // process the last Quadruplet
>     //
>     // first two octets are present always, process them
>     if (!isData( (d1 = rawInputData[ rawInputIndex++ ]) ) ||
>         !isData( (d2 = rawInputData[ rawInputIndex++ ]) ))
195a328
>         // if found "no data" just return NULL
197c330
<         return 0;//if found "no data" just return null
---
>         return 0;
200,201c333,334
<     b1 = base64Alphabet[d1]; 
<     b2 = base64Alphabet[d2];
---
>     b1 = base64Inverse[ d1 ]; 
>     b2 = base64Inverse[ d2 ];
203,205c336,338
<     // the last two octets
<     d3 = normalizedBase64Data[dataIndex++];
<     d4 = normalizedBase64Data[dataIndex++];
---
>     // try to process last two octets
>     d3 = rawInputData[ rawInputIndex++ ];
>     d4 = rawInputData[ rawInputIndex++ ];
209c342
<         //Check if they are PAD characters
---
>         // check if last two are PAD characters
212,213c345,346
<             //Two PAD e.g. 3c[Pad][Pad]
<             if ((b2 & 0xf) != 0)//last 4 bits should be zero
---
>             // two PAD e.g. 3c==
>             if ((b2 & 0xf) != 0) // last 4 bits should be zero
219,220c352
<             decodedData[encodedIndex++] = set1stOctect(b1, b2);
<             decodedData[encodedIndex] = 0;            
---
>             decodedData[ outputIndex++ ] = set1stOctet(b1, b2);
222c354
<         else if (!isPad( d3) && isPad(d4)) 
---
>         else if (!isPad( d3 ) && isPad( d4 )) 
224,226c356,358
<             //One PAD  e.g. 3cQ[Pad]
<             b3 = base64Alphabet[ d3 ];
<             if ((b3 & 0x3) != 0)//last 2 bits should be zero
---
>             // one PAD e.g. 3cQ=
>             b3 = base64Inverse[ d3 ];
>             if (( b3 & 0x3 ) != 0 ) // last 2 bits should be zero
232,234c364,365
<             decodedData[encodedIndex++] = set1stOctect(b1, b2);
<             decodedData[encodedIndex++] = set2ndOctect(b2, b3);
<             decodedData[encodedIndex] = 0;            
---
>             decodedData[ outputIndex++ ] = set1stOctet( b1, b2 );
>             decodedData[ outputIndex++ ] = set2ndOctet( b2, b3 );
237a369
>             // an error like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data 
239c371
<             return 0;//an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data 
---
>             return 0;
243,249c375,381
<     { //No PAD e.g 3cQl
<         b3 = base64Alphabet[d3];
<         b4 = base64Alphabet[d4];
<         decodedData[encodedIndex++] = set1stOctect(b1, b2);
<         decodedData[encodedIndex++] = set2ndOctect(b2, b3);
<         decodedData[encodedIndex++] = set3rdOctect(b3, b4); 
<         decodedData[encodedIndex] = 0; 
---
>     { 
>         // no PAD e.g 3cQl
>         b3 = base64Inverse[ d3 ];
>         b4 = base64Inverse[ d4 ];
>         decodedData[ outputIndex++ ] = set1stOctet( b1, b2 );
>         decodedData[ outputIndex++ ] = set2ndOctet( b2, b3 );
>         decodedData[ outputIndex++ ] = set3rdOctet( b3, b4 );
252c384,387
<     base64DataLen = encodedIndex;
---
>     // write out the end of string
>     decodedData[ outputIndex ] = 0; 
>     outputLength = outputIndex;
> 
263a399,404
>     isInitialized = true;
> 
>     // create inverse table for base64 decoding
>     // if base64Alphabet[ 17 ] = 'R', then base64Inverse[ 'R' ] = 17
>     // for characters not in base64Alphabet the base64Inverse[] = -1
> 
265c406
<     // [0] = -1, [255] = -1
---
>     // set all fields to -1
267c408
<         base64Alphabet[i] = (XMLCh)-1; 
---
>         base64Inverse[i] = (XMLCh)-1; 
269,292c410,412
<     // [65] = 0, [90] = 25
<     for ( i = chLatin_Z; i >= chLatin_A; i-- ) 
<         base64Alphabet[i] = (XMLCh)( i - chLatin_A );
<     
<     // [97] = 0 + 26 = 26, [122] = 25 + 26 = 51 
<     for ( i = chLatin_z; i >= chLatin_a; i-- )
<         base64Alphabet[i] = (XMLCh)( i - chLatin_a + 26 );
< 
<     // [48] = 0 + 52, [57] = 9 + 52
<     for ( i = chDigit_9; i >= chDigit_0; i-- ) 
<         base64Alphabet[i] = (XMLCh)( i- chDigit_0 + 52 );
< 
<     // [43] = 62
<     // [47] = 63
<     base64Alphabet[chPlus] = (XMLCh) 62; 
<     base64Alphabet[chForwardSlash] = (XMLCh) 63;
< 
<     isInitialized=true;
< 
<     //
<     // index:  0       42 43         47  48       57     65          90       97         122       254
<     // char:              '+'        '/' '0'      '9'    'A'         'Z'      'a'        'z'
<     // value: -1 ...  -1  62 -1...   63  52       61      0          25  -1.. 26         51  -1...
<     //
---
>     // compute inverse table
>     for ( i = 0; i < 64; i++ ) 
>         base64Inverse[ base64Alphabet[i] ] = (XMLCh)i;
295c415
< bool Base64::isData(const XMLCh& octect) 
---
> bool Base64::isData(const XMLCh& octet) 
298c418
<     if (( octect >= BASELENGTH ) || ( octect < 0 ))
---
>     if (( octet >= BASELENGTH ) || ( octet < 0 ))
301c421
<     return( base64Alphabet[octect] != (XMLCh) -1);
---
>     return( base64Inverse[octet] != (XMLCh) -1);
