opennurbs_base64.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018 
00020 //
00021 // ON_DecodeBase64
00022 // 
00023 
00024 ON_DecodeBase64::ON_DecodeBase64()
00025 {
00026   Begin();
00027 }
00028 
00029 ON_DecodeBase64::~ON_DecodeBase64()
00030 {
00031   Begin();
00032 }
00033 
00034 void ON_DecodeBase64::Begin()
00035 {
00036   m_decode_count = 0;
00037   m_output_count = 0;
00038   memset(m_output,0,512);
00039   m_status = 0;
00040   m_cache_count = 0;
00041   m_cache[0] = 0;
00042   m_cache[1] = 0;
00043   m_cache[2] = 0;
00044   m_cache[3] = 0;  
00045 }
00046 
00047 bool ON_DecodeBase64::End()
00048 {
00049   if ( 0 != m_status )
00050   {
00051     if ( 3 == m_status || 4 == m_status )
00052     {
00053       if ( 0 != m_output_count )
00054         SetError(); // all output should have been flushed
00055       else
00056         m_status = 5; // finished
00057     }
00058     else if ( 1 != m_status )
00059       SetError();
00060   }
00061   else
00062   {
00063     if ( m_output_count > 0 )
00064     {
00065       Output();
00066       m_output_count = 0;
00067     }
00068     m_status = 5; // finished
00069   }
00070   m_output_count = 0;
00071   memset(m_output,0,512);
00072   return ( 1 != m_status );
00073 }
00074 
00075 void ON_DecodeBase64::SetError()
00076 {
00077   // unrecoverable error
00078   ON_ERROR("ON_DecodeBase64::Decode - error");
00079   m_status = 1;
00080 }
00081 
00082 const bool ON_DecodeBase64::Error() const
00083 {
00084   return (1 == m_status);
00085 }
00086 
00087 void ON_DecodeBase64::DecodeHelper1()
00088 {
00089   // Send the last byte of decoded output when the
00090   // last 4 bytes of the base64 encoded string are "**=="
00091   // This function is called at most one time to
00092   // decode the last base 64 quartet into the final
00093   // byte of output.
00094 
00095   union
00096   {
00097     ON__INT32 i;
00098     unsigned char b[4];
00099   } u;
00100   m_status = 0;
00101   if ( m_output_count >= 512 )
00102   {
00103     Output();
00104     m_output_count = 0;
00105   }
00106   u.i = 4*m_cache[0] + m_cache[1]/16;
00107   m_output[m_output_count++] = u.b[0];
00108   Output();
00109   m_output_count = 0;
00110 }
00111 
00112 void ON_DecodeBase64::DecodeHelper2()
00113 {
00114   // Send the last 2 bytes of decoded output when the
00115   // last 4 bytes of base64 encoded string are "***=".
00116   // This function is called at most one time to
00117   // decode the last base 64 quartet into the final
00118   // two bytes of output.
00119 
00120   union
00121   {
00122     ON__INT32 i;
00123     unsigned char b[4];
00124   } u;
00125   m_status = 0;
00126   if ( m_output_count >= 511 )
00127   {
00128     Output();
00129     m_output_count = 0;
00130   }
00131 
00132   u.i = 1024*m_cache[0] + 16*m_cache[1] + m_cache[2]/4;
00133   m_output[m_output_count++] = u.b[1];
00134   m_output[m_output_count++] = u.b[0];
00135   Output();
00136   m_output_count = 0;
00137 }
00138 
00139 const char* ON_DecodeBase64::Decode(const char* base64str)
00140 {
00141   union
00142   {
00143     ON__INT32 i;
00144     unsigned char b[4];
00145   } u;
00146   ON__INT32 i;
00147   unsigned char* outbuf;
00148 
00149   //#if defined(_DEBUG)
00150   //  if (    m_cache_count < 0
00151   //       || m_cache_count >= 4
00152   //       || m_cache_count != (m_decode_count % 4) 
00153   //     )
00154   //  {
00155   //    // algorithm error
00156   //    SetError();
00157   //    return 0;
00158   //  }
00159   //#endif
00160 
00161   if ( m_status )
00162   {
00163     // rarely executed code
00164     if ( 1 == m_status )
00165     {
00166       return 0;
00167     }
00168     if ( base64str )
00169     {
00170       i = *base64str;
00171       if      (i >= 65 && i <=  90) i =  1;
00172       else if (i >= 97 && i <= 122) i =  1;
00173       else if (i >= 48 && i <=  57) i =  1;
00174       else if ('+' == i)            i =  1; 
00175       else if ('/' == i)            i =  1;
00176       else if ('=' == i)            i = -1;
00177       else
00178       {
00179         return 0;
00180       }
00181 
00182       if ( 2 != m_status || -1 != m_cache[2] )
00183       {
00184         SetError();
00185         return 0;
00186       }
00187       if ( -1 != i )
00188       {
00189         // base64 encoded strings are parsed in groups of 4 characters.
00190         // When we enter this part of the Decode function, m_status is
00191         // either 1 (error occured earlier) or 2.  
00192         // A 2 means the previous character we parsed was the 3rd
00193         // of the group and it was an equal sign.  In this case, the
00194         // the 4th character in the group must be an equal sign and
00195         // the group encodes a single byte.
00196         SetError();
00197         return 0;
00198       }
00199     }
00200   }
00201 
00202   if (!base64str)
00203     return 0;
00204 
00205   outbuf = m_output+m_output_count;
00206 
00207   for(;;)
00208   {
00209     while ( m_cache_count < 4 )
00210     {
00211       // base 64 encodes 3 bytes as a 4 digit base 64 number.
00212       // The base 64 "digits" are A-z,a-z,0-9,+ and /.  The
00213       // values of these "digits" are listed below.
00214       // 'A' ->  0
00215       // ...
00216       // 'Z' -> 25
00217       // 'a' -> 26
00218       // ...
00219       // 'z' -> 51
00220       // '0' -> 52
00221       // ...
00222       // '9' -> 61
00223       // '+' -> 62
00224       // '/' -> 63
00225       // '=' padding used to encode the last one or two bytes
00226       //     If the 3rd and 4th characters in the quartet are
00227       //     equal signs, the quartet represents a single byte
00228       //     as a 2 digit base 64 number.  
00229       //     If the 4th character in the quartet is an equal sign,
00230       //     the quartet represents two bytes as a 3 digit 
00231       //     base 64 number.  
00232       i = *base64str++;
00233       if      (i >= 65 && i <=  90) i -= 65;
00234       else if (i >= 97 && i <= 122) i -= 71;
00235       else if (i >= 48 && i <=  57) i +=  4;
00236       else if ('+' == i) i = 62; 
00237       else if ('/' == i) i = 63;
00238       else if ('=' == i) 
00239       {
00240         if ( m_cache_count < 2 )
00241         {
00242           // An equal sign cannot be the 1rst or 2nd character
00243           // in a 4 character block
00244           SetError();
00245           return 0;
00246         }
00247         if ( 2 == m_cache_count )
00248         {
00249           // This equal sign is the 3rd character.  The next 
00250           // character must also be an = sign or the input is
00251           // not valid.
00252           m_status = 2;
00253         }
00254         else // 3 == m_cache_count
00255         {
00256           // This equal sign is the 4th character.
00257           // This must be the last encoded character.
00258           if ( -1 == m_cache[2] )
00259           {
00260             // block ends with 2 equal signs
00261             // and will decode into a single byte
00262             m_status = 3;
00263             m_cache[m_cache_count++] = -1;
00264             m_decode_count++;
00265             DecodeHelper1();
00266             return base64str;
00267           }
00268           else
00269           {
00270             // block ends with 1 equal sign and will
00271             // decode into 2 bytes.
00272             m_status = 4;
00273             m_cache[m_cache_count++] = -1;
00274             m_decode_count++;
00275             DecodeHelper2();
00276             return base64str;
00277           }
00278         }
00279         i = -1;
00280       }
00281       else
00282       {
00283         // end of valid portion of this base64str 
00284         return (base64str-1);
00285       }
00286       m_cache[m_cache_count++] = i;
00287       m_decode_count++;
00288     }
00289 
00290     m_cache_count = 0;
00291 
00292     // 3 bytes of output
00293     if ( m_output_count >= 510 )
00294     {
00295       Output();
00296       m_output_count = 0;
00297       outbuf = m_output;
00298     }
00299     u.i = m_cache[3] + 64*(m_cache[2] + 64*(m_cache[1] + 64*m_cache[0]));
00300     *outbuf++ = u.b[2];
00301     *outbuf++ = u.b[1];
00302     *outbuf++ = u.b[0];
00303     m_output_count += 3;
00304   }
00305 
00306   //return 0;
00307 }
00308 
00309 const char* ON_DecodeBase64::Decode(const char* base64str, size_t base64str_count)
00310 {
00311   char* sEnd;
00312   const char* p;
00313   char s[1025];
00314   if ( 0 == base64str )
00315     return 0;
00316   sEnd = s + 1024;
00317   *sEnd = 0;
00318   while ( base64str_count >= 1024 )
00319   {
00320     memcpy(s,base64str,1024);
00321     p = Decode(s);
00322     if ( 0 == p )
00323       return 0;
00324     if ( p != sEnd )
00325     {
00326       return base64str + (p - s);
00327     }
00328     base64str += 1024;
00329     base64str_count -= 1024;
00330   }
00331   if ( base64str_count > 0 )
00332   {
00333     memcpy(s,base64str,base64str_count);
00334     s[base64str_count]=0;
00335     p = Decode(s);
00336     if ( 0 == p )
00337       return 0;
00338     base64str += (p - s);
00339   }
00340   return base64str;
00341 }
00342 
00343 const wchar_t* ON_DecodeBase64::Decode(const wchar_t* base64str)
00344 {
00345   const wchar_t* p;
00346   wchar_t w;
00347   if ( 0 == base64str )
00348     return 0;
00349   p = base64str;
00350   for(;;)
00351   {
00352     w = *p++;
00353     if ( w < 32 || w > 122 )
00354       break;
00355   }
00356   return Decode(base64str,p-base64str);
00357 }
00358 
00359 const wchar_t* ON_DecodeBase64::Decode(const wchar_t* base64str, size_t base64str_count)
00360 {
00361   char* sEnd;
00362   const char* p;
00363   char s[1025];
00364   size_t i;
00365   wchar_t w;
00366   if ( 0 == base64str )
00367     return 0;
00368   sEnd = s + 1024;
00369   *sEnd = 0;
00370   while ( base64str_count >= 1024 )
00371   {
00372     for(i=0;i<1024;i++)
00373     {
00374       w = base64str[i];
00375       if ( w < 32 || w > 122 )
00376       {
00377         s[i] = 0;
00378         break;
00379       }
00380       s[i] = (char)w;
00381     }
00382     p = Decode(s);
00383     if ( 0 == p )
00384       return 0;
00385     if ( p != sEnd )
00386     {
00387       return base64str + (p - s);
00388     }
00389     base64str += 1024;
00390     base64str_count -= 1024;
00391   }
00392   if ( base64str_count > 0 )
00393   {
00394     for(i=0;i<base64str_count;i++)
00395     {
00396       w = base64str[i];
00397       if ( w < 32 || w > 122 )
00398       {
00399         s[i] = 0;
00400         break;
00401       }
00402       s[i] = (char)w;
00403     }
00404     s[i] = 0;
00405     p = Decode(s);
00406     if ( 0 == p )
00407       return 0;
00408     base64str += (p - s);
00409   }
00410   return base64str;
00411 }
00412 
00413 // virtual 
00414 void ON_DecodeBase64::Output()
00415 {
00416   // default does nothing.
00417 }
00418 
00419 /*
00421 //
00422 // ON_EncodeBase64
00423 // 
00424 
00425 ON_EncodeBase64::ON_EncodeBase64()
00426 {
00427   Begin();
00428 }
00429 
00430 ON_EncodeBase64::~ON_EncodeBase64()
00431 {
00432   Begin();
00433 }
00434 
00435 //vitrual
00436 void ON_EncodeBase64::Output()
00437 {
00438   // The default does nothing - override this function
00439   // if you want to do something useful with the output.
00440 }
00441 
00442 void ON_EncodeBase64::Begin()
00443 {
00444   m_encode_count = 0;
00445   m_output_count = 0;
00446   memset(m_output,0,80);
00447   m_unused2 = 0;
00448   m_input_count = 0;
00449   memset(m_input,0,64);
00450 }
00451 
00452 void ON_EncodeBase64::EncodeHelper1(const unsigned char* inbuf, char* outbuf )
00453 {
00454   // base64 encode the final byte of input into 4 bytes of outbuf.
00455   unsigned char c;
00456   
00457   c = (*inbuf >> 2);
00458 
00459   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00460   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00461   *outbuf++ = c;
00462 
00463   c = (*inbuf & 3) << 4;
00464 
00465   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00466   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00467   *outbuf++ = c;
00468 
00469   *outbuf++ = '=';
00470   *outbuf   = '=';
00471 }
00472 
00473 void ON_EncodeBase64::EncodeHelper2(const unsigned char* inbuf, char* outbuf )
00474 {
00475   // base64 encode the final 2 bytes of input into 4 bytes of outbuf.
00476   unsigned char b, c;
00477   
00478   b = *inbuf++;
00479   c = (b >> 2);
00480 
00481   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00482   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00483   *outbuf++ = c;
00484 
00485   c = (b & 3) << 4;
00486   b = *inbuf;
00487   c |= (b & 0xF0) >> 4;
00488 
00489   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00490   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00491   *outbuf++ = c;
00492 
00493   c = (b & 0x0F) << 2;
00494 
00495   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00496   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00497   *outbuf++ = c;
00498 
00499   *outbuf  = '=';
00500 }
00501 
00502 
00503 void ON_EncodeBase64::EncodeHelper3(const unsigned char* inbuf, char* outbuf )
00504 {
00505   // base64 encode 3 bytes from inbuf into 4 bytes of outbuf.
00506   unsigned char b, c;
00507   
00508   b = *inbuf++;
00509   c = (b >> 2);
00510 
00511   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00512   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00513   *outbuf++ = c;
00514 
00515   c = (b & 3) << 4;
00516   b = *inbuf++;
00517   c |= (b & 0xF0) >> 4;
00518 
00519   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00520   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00521   *outbuf++ = c;
00522 
00523   c = (b & 0x0F) << 2;
00524   b = *inbuf++;
00525   c |= (b&0xC0) >> 6;
00526 
00527   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00528   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00529   *outbuf++ = c;
00530 
00531   b &= 0x3F;
00532   if ( b < 26 ) b += 65; else if ( b < 52 ) b += 71; 
00533   else if ( b < 62 ) b -= 4; else b = (b&1) ? '/' : '+';
00534   *outbuf++ = b;
00535 }
00536 
00537 void ON_EncodeBase64::EncodeHelper57(const unsigned char* inbuf )
00538 {
00539   // base64 encode 57 bytes from inbuf and put results in m_output[]
00540   //
00541   // Encoding 57 input bytes creates 76 output bytes and 76
00542   // is the maximum line length for base64 encoding.
00543   char* outbuf = m_output;
00544   EncodeHelper3(inbuf,outbuf); 
00545   inbuf += 3; outbuf += 4;
00546   EncodeHelper3(inbuf,outbuf); 
00547   inbuf += 3; outbuf += 4;
00548   EncodeHelper3(inbuf,outbuf); 
00549   inbuf += 3; outbuf += 4;
00550   EncodeHelper3(inbuf,outbuf); 
00551   inbuf += 3; outbuf += 4;
00552   EncodeHelper3(inbuf,outbuf); 
00553   inbuf += 3; outbuf += 4;
00554   EncodeHelper3(inbuf,outbuf); 
00555   inbuf += 3; outbuf += 4;
00556   EncodeHelper3(inbuf,outbuf); 
00557   inbuf += 3; outbuf += 4;
00558   EncodeHelper3(inbuf,outbuf); 
00559   inbuf += 3; outbuf += 4;
00560   EncodeHelper3(inbuf,outbuf); 
00561   inbuf += 3; outbuf += 4;
00562   EncodeHelper3(inbuf,outbuf); 
00563   inbuf += 3; outbuf += 4;
00564   EncodeHelper3(inbuf,outbuf); 
00565   inbuf += 3; outbuf += 4;
00566   EncodeHelper3(inbuf,outbuf); 
00567   inbuf += 3; outbuf += 4;
00568   EncodeHelper3(inbuf,outbuf); 
00569   inbuf += 3; outbuf += 4;
00570   EncodeHelper3(inbuf,outbuf); 
00571   inbuf += 3; outbuf += 4;
00572   EncodeHelper3(inbuf,outbuf); 
00573   inbuf += 3; outbuf += 4;
00574   EncodeHelper3(inbuf,outbuf); 
00575   inbuf += 3; outbuf += 4;
00576   EncodeHelper3(inbuf,outbuf); 
00577   inbuf += 3; outbuf += 4;
00578   EncodeHelper3(inbuf,outbuf); 
00579   inbuf += 3; outbuf += 4;
00580   EncodeHelper3(inbuf,outbuf); 
00581   memset(outbuf+4,0,4);
00582   m_encode_count += 57;
00583 }
00584 
00585 void ON_EncodeBase64::Encode( const void* buffer, size_t sizeof_buffer )
00586 {
00587   // code is designed for speed
00588   unsigned int sz;
00589   const unsigned char* inbuf;
00590   if ( sizeof_buffer <= 0 || !buffer )
00591     return;
00592 
00593   if ( m_input_count )
00594   {
00595     // residual input left from the previous call to Encode()
00596     sz = 57 - m_input_count;
00597     if ( sizeof_buffer < sz )
00598     {
00599       // still don't have 57 bytes of input
00600       memcpy(m_input+m_input_count,buffer,sizeof_buffer);
00601       m_input_count += ((int)sizeof_buffer); // safe cast - sizeof_buffer < 57
00602       return;
00603     }
00604 
00605     // m_input[] has 57 bytes - encode it
00606     memcpy(m_input+m_input_count,buffer,sz);
00607     EncodeHelper57(m_input);
00608     m_output_count = 76;
00609     m_input_count = 0;
00610     Output();
00611     if ( sizeof_buffer == sz )
00612     {
00613       // no input left
00614       m_output_count = 0;
00615       *m_output = 0;
00616       return;
00617     }
00618 
00619     // deal with remaining input
00620     buffer = ((const unsigned char*)buffer + sz);
00621     sizeof_buffer -= sz;
00622   }
00623 
00624   m_output_count = 76;
00625   inbuf = (const unsigned char*)buffer;
00626   while(sizeof_buffer >= 57 )
00627   {
00628     // encode 57 bytes in m_input_count[]
00629     EncodeHelper57(inbuf);
00630     Output();  
00631     inbuf += 57;
00632     sizeof_buffer -= 57;
00633   }
00634 
00635   if ( sizeof_buffer )
00636   {
00637     // store what's left of the input in m_input[]
00638     memcpy(m_input,inbuf,sizeof_buffer);
00639     m_input_count = (int)sizeof_buffer; // safe cast - sizeof_buffer < 57
00640   }
00641 
00642   m_output_count = 0;
00643   *m_output = 0;
00644 }
00645 
00646 void ON_EncodeBase64::End()
00647 {
00648   const unsigned char* inbuf;
00649   char* outbuf;
00650   m_output_count = 0;
00651   if ( m_input_count > 0 )
00652   {
00653     // flush rest of input
00654     inbuf = m_input;
00655     outbuf = m_output;
00656     while ( m_input_count >= 3 )
00657     {
00658       EncodeHelper3(inbuf,outbuf);
00659       inbuf += 3;
00660       outbuf += 4;
00661       m_input_count -= 3;
00662       m_output_count += 4;
00663       m_encode_count += 3;
00664     }
00665     if ( 1 == m_input_count )
00666     {
00667       // 1 byte of input left
00668       EncodeHelper1(inbuf,outbuf);
00669       outbuf += 4;
00670       m_output_count += 4;
00671       m_encode_count++;
00672     }
00673     else if ( 2 == m_input_count )
00674     {
00675       // 2 bytes of input left
00676       EncodeHelper2(inbuf,outbuf);
00677       outbuf += 4;
00678       m_output_count += 4;
00679       m_encode_count += 2;
00680     }
00681     memset(outbuf,0,80-m_output_count);
00682     m_input_count = 0;
00683     Output();
00684     m_output_count = 0;
00685   }
00686   *m_output = 0;
00687 }
00688 
00689 */
00690 
00694 
00695 
00696 ON_Base64EncodeStream::ON_Base64EncodeStream()
00697 : m_out_callback_function(0)
00698 , m_out_callback_context(0)
00699 , m_in_size(0)
00700 , m_out_size(0)
00701 , m_in_crc(0)
00702 , m_out_crc(0)
00703 , m_implementation(0)
00704 , m_reserved(0)
00705 {}
00706 
00707 ON_Base64EncodeStream::~ON_Base64EncodeStream()
00708 {
00709 
00710   if ( 0 != m_implementation )
00711   {
00712     onfree(m_implementation);
00713     m_implementation = 0;
00714   }
00715 }
00716 
00717 void ON_Base64EncodeStream::ErrorHandler()
00718 {
00719   // place holder for error handing
00720   ON_ERROR("ON_UncompressStream error");
00721 }
00722 
00723 class ON_Base64EncodeImplementation
00724 {
00725 public:
00726   // input waiting to be encoded
00727   // At most 56 bytes can be waiting to be processed in m_in_buffer[].
00728   // m_in_buffer[] is full when it has 57 bytes.
00729   ON__UINT32 m_in_buffer_size;
00730   unsigned char m_in_buffer[64];
00731 
00732   // When the output stream handler is called, m_out_buffer[]
00733   // is a null terminated string with 4 to 76 characters of 
00734   // base64 encoded output.
00735   char m_out_buffer[80];
00736 };
00737 
00738 
00739 bool ON_Base64EncodeStream::Begin()
00740 {
00741   if ( 0 != m_implementation )
00742   {
00743     onfree(m_implementation);
00744     m_implementation = 0;
00745   }
00746 
00747   // zero these because the same instance of an 
00748   // ON_UncompressStream class may be used multiple times.
00749   m_in_size = 0;
00750   m_out_size = 0;
00751   m_in_crc = 0;
00752   m_out_crc = 0;
00753 
00754   ON_Base64EncodeImplementation* imp = (ON_Base64EncodeImplementation*)onmalloc(sizeof(*imp));
00755   memset(imp,0,sizeof(*imp));
00756   m_implementation = imp;
00757 
00758   return true;
00759 }
00760 
00761 static void EncodeBase64Helper1(const unsigned char* inbuf, char* outbuf )
00762 {
00763   // base64 encode the final byte of input into 4 bytes of outbuf.
00764   unsigned char c;
00765   
00766   c = (*inbuf >> 2);
00767 
00768   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00769   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00770   *outbuf++ = c;
00771 
00772   c = (*inbuf & 3) << 4;
00773 
00774   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00775   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00776   *outbuf++ = c;
00777 
00778   *outbuf++ = '=';
00779   *outbuf   = '=';
00780 }
00781 
00782 static void EncodeBase64Helper2(const unsigned char* inbuf, char* outbuf )
00783 {
00784   // base64 encode the final 2 bytes of input into 4 bytes of outbuf.
00785   unsigned char b, c;
00786   
00787   b = *inbuf++;
00788   c = (b >> 2);
00789 
00790   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00791   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00792   *outbuf++ = c;
00793 
00794   c = (b & 3) << 4;
00795   b = *inbuf;
00796   c |= (b & 0xF0) >> 4;
00797 
00798   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00799   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00800   *outbuf++ = c;
00801 
00802   c = (b & 0x0F) << 2;
00803 
00804   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00805   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00806   *outbuf++ = c;
00807 
00808   *outbuf  = '=';
00809 }
00810 
00811 
00812 static void EncodeBase64Helper3(const unsigned char* inbuf, char* outbuf )
00813 {
00814   // base64 encode 3 bytes from inbuf into 4 bytes of outbuf.
00815   unsigned char b, c;
00816   
00817   b = *inbuf++;
00818   c = (b >> 2);
00819 
00820   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00821   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00822   *outbuf++ = c;
00823 
00824   c = (b & 3) << 4;
00825   b = *inbuf++;
00826   c |= (b & 0xF0) >> 4;
00827 
00828   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00829   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00830   *outbuf++ = c;
00831 
00832   c = (b & 0x0F) << 2;
00833   b = *inbuf++;
00834   c |= (b&0xC0) >> 6;
00835 
00836   if ( c < 26 ) c += 65; else if ( c < 52 ) c += 71; 
00837   else if ( c < 62 ) c -= 4; else c = (c&1) ? '/' : '+';
00838   *outbuf++ = c;
00839 
00840   b &= 0x3F;
00841   if ( b < 26 ) b += 65; else if ( b < 52 ) b += 71; 
00842   else if ( b < 62 ) b -= 4; else b = (b&1) ? '/' : '+';
00843   *outbuf++ = b;
00844 }
00845 
00846 static void EncodeBase64Helper57(const unsigned char* inbuf, char* outbuf )
00847 {
00848   // base64 encode 57 bytes from inbuf and put results in m_output[]
00849   //
00850   // Encoding 57 input bytes creates 76 output bytes and 76
00851   // is the maximum line length for base64 encoding.
00852   EncodeBase64Helper3(inbuf,outbuf); 
00853   inbuf += 3; outbuf += 4;
00854   EncodeBase64Helper3(inbuf,outbuf); 
00855   inbuf += 3; outbuf += 4;
00856   EncodeBase64Helper3(inbuf,outbuf); 
00857   inbuf += 3; outbuf += 4;
00858   EncodeBase64Helper3(inbuf,outbuf); 
00859   inbuf += 3; outbuf += 4;
00860   EncodeBase64Helper3(inbuf,outbuf); 
00861   inbuf += 3; outbuf += 4;
00862   EncodeBase64Helper3(inbuf,outbuf); 
00863   inbuf += 3; outbuf += 4;
00864   EncodeBase64Helper3(inbuf,outbuf); 
00865   inbuf += 3; outbuf += 4;
00866   EncodeBase64Helper3(inbuf,outbuf); 
00867   inbuf += 3; outbuf += 4;
00868   EncodeBase64Helper3(inbuf,outbuf); 
00869   inbuf += 3; outbuf += 4;
00870   EncodeBase64Helper3(inbuf,outbuf); 
00871   inbuf += 3; outbuf += 4;
00872   EncodeBase64Helper3(inbuf,outbuf); 
00873   inbuf += 3; outbuf += 4;
00874   EncodeBase64Helper3(inbuf,outbuf); 
00875   inbuf += 3; outbuf += 4;
00876   EncodeBase64Helper3(inbuf,outbuf); 
00877   inbuf += 3; outbuf += 4;
00878   EncodeBase64Helper3(inbuf,outbuf); 
00879   inbuf += 3; outbuf += 4;
00880   EncodeBase64Helper3(inbuf,outbuf); 
00881   inbuf += 3; outbuf += 4;
00882   EncodeBase64Helper3(inbuf,outbuf); 
00883   inbuf += 3; outbuf += 4;
00884   EncodeBase64Helper3(inbuf,outbuf); 
00885   inbuf += 3; outbuf += 4;
00886   EncodeBase64Helper3(inbuf,outbuf); 
00887   inbuf += 3; outbuf += 4;
00888   EncodeBase64Helper3(inbuf,outbuf); 
00889   outbuf[4] = 0;
00890 }
00891 
00892 
00893 bool ON_Base64EncodeStream::In(
00894     ON__UINT64 in_buffer_size,
00895     const void* in_buffer
00896     )
00897 {
00898   if ( in_buffer_size <= 0 )
00899     return true;
00900 
00901   if ( 0 == m_implementation )
00902   {
00903     ErrorHandler();
00904     return false;
00905   }
00906 
00907   if ( 0 == in_buffer )
00908   {
00909     ErrorHandler();
00910     return false;
00911   }
00912   
00913   bool rc = false;
00914   ON__UINT32 crc1;
00915   ON__UINT32 sz;
00916 
00917   ON_Base64EncodeImplementation* imp = (ON_Base64EncodeImplementation*)m_implementation;
00918   if ( imp->m_in_buffer_size > 0 )
00919   {
00920     // residual input left from the previous call to In()
00921     sz = 57 - imp->m_in_buffer_size;
00922     if ( in_buffer_size < sz )
00923     {
00924       // still don't have sizeof(imp->m_in_buffer_size) bytes of input
00925       sz = (ON__UINT32)in_buffer_size; // cast is safe because in_buffer_size < sizeof(imp->m_in_buffer_size) <= 8192
00926       memcpy( imp->m_in_buffer + imp->m_in_buffer_size, in_buffer, sz );
00927       imp->m_in_buffer_size += sz;
00928       return true;
00929     }
00930 
00931     memcpy( imp->m_in_buffer + imp->m_in_buffer_size, in_buffer, sz );
00932     in_buffer = ((const unsigned char*)in_buffer) + sz;
00933     in_buffer_size -= sz;
00934 
00935     EncodeBase64Helper57(imp->m_in_buffer,imp->m_out_buffer);
00936     imp->m_in_buffer_size = 0;
00937 
00938     crc1 = ON_CRC32(m_out_crc,76,imp->m_out_buffer);
00939     rc = ( 0 != m_out_callback_function )
00940         ? m_out_callback_function(m_out_callback_context,76,imp->m_out_buffer)
00941         : Out(m_out_callback_context,76,imp->m_out_buffer);
00942     if ( !rc )
00943     {
00944       onfree(m_implementation);
00945       m_implementation = 0;
00946       return false;
00947     }
00948     m_in_crc = ON_CRC32(m_in_crc,57,imp->m_in_buffer);
00949     m_in_size += 57;
00950     m_out_crc = crc1;
00951     m_out_size += 76;
00952   }
00953 
00954   while(in_buffer_size >= 57 )
00955   {
00956     // base 64 encode 57 input bytes to create 76 output bytes
00957     EncodeBase64Helper57((const unsigned char*)in_buffer,imp->m_out_buffer);
00958     crc1 = ON_CRC32(m_out_crc,76,imp->m_out_buffer);
00959     rc = ( 0 != m_out_callback_function )
00960         ? m_out_callback_function(m_out_callback_context,76,imp->m_out_buffer)
00961         : Out(m_out_callback_context,76,imp->m_out_buffer);
00962     if ( !rc )
00963     {
00964       onfree(m_implementation);
00965       m_implementation = 0;
00966       return false;
00967     }
00968     m_in_crc = ON_CRC32(m_in_crc,57,in_buffer);
00969     m_in_size += 57;
00970     m_out_crc = crc1;
00971     m_out_size += 76;
00972     in_buffer = ((const unsigned char*)in_buffer) + 57;
00973     in_buffer_size -= 57;
00974   }
00975 
00976   if ( in_buffer_size > 0 )
00977   {
00978     // store what's left of the input in imp->m_in_buffer[]
00979     memcpy(imp->m_in_buffer,in_buffer,(size_t)in_buffer_size);
00980   }
00981   imp->m_in_buffer_size = (ON__UINT32)in_buffer_size; // safe cast - sizeof_buffer < 57
00982 
00983   return true;
00984 }
00985 
00986 bool ON_Base64EncodeStream::End()
00987 {
00988   if ( 0 == m_implementation )
00989   {
00990     ErrorHandler();
00991     return false;
00992   }
00993   
00994   bool rc = true;
00995   ON_Base64EncodeImplementation* imp = (ON_Base64EncodeImplementation*)m_implementation;
00996   if ( imp->m_in_buffer_size > 0 )
00997   {
00998     // residual input left from the final call to In()
00999     const unsigned char* in_buffer = imp->m_in_buffer;
01000     ON__UINT32 in_buffer_size = imp->m_in_buffer_size;
01001     ON__UINT32 out_buffer_size = 0;
01002     while ( in_buffer_size >= 3 )
01003     {
01004       EncodeBase64Helper3( in_buffer, &imp->m_out_buffer[out_buffer_size] );
01005       in_buffer += 3;
01006       out_buffer_size += 4;
01007       in_buffer_size -= 3;
01008     }
01009     if ( 1 == in_buffer_size )
01010     {
01011       // 1 byte of input left
01012       EncodeBase64Helper1(in_buffer,&imp->m_out_buffer[out_buffer_size]);
01013       out_buffer_size += 4;
01014     }
01015     else if ( 2 == in_buffer_size )
01016     {
01017       // 2 bytes of input left
01018       EncodeBase64Helper2(in_buffer,&imp->m_out_buffer[out_buffer_size]);
01019       out_buffer_size += 4;
01020     }
01021     imp->m_out_buffer[out_buffer_size] = 0;
01022 
01023     ON__UINT32 crc1 = ON_CRC32(m_out_crc,out_buffer_size,imp->m_out_buffer);
01024     rc = ( 0 != m_out_callback_function )
01025         ? m_out_callback_function(m_out_callback_context,out_buffer_size,imp->m_out_buffer)
01026         : Out(m_out_callback_context,out_buffer_size,imp->m_out_buffer);
01027     if ( rc )
01028     {
01029       m_in_crc = ON_CRC32(m_in_crc,imp->m_in_buffer_size,imp->m_in_buffer);
01030       m_in_size += imp->m_in_buffer_size;
01031       m_out_crc = crc1;
01032       m_out_size += out_buffer_size;
01033     }
01034   }
01035 
01036   onfree(m_implementation);
01037   m_implementation = 0;
01038 
01039   return rc;
01040 }
01041 
01042 bool ON_Base64EncodeStream::Out( void*, ON__UINT32, const char* )
01043 {
01044   // default base 64 encoded stream handler does nothing.
01045   return true;
01046 }
01047 
01048 bool ON_Base64EncodeStream::SetCallback( 
01049     ON_StreamCallbackFunction out_callback_function,
01050     void* out_callback_context
01051     )
01052 {
01053   m_out_callback_function = out_callback_function;
01054   m_out_callback_context = out_callback_context;
01055   return true;
01056 }
01057 
01058 ON_StreamCallbackFunction ON_Base64EncodeStream::CallbackFunction() const
01059 {
01060   return m_out_callback_function;
01061 }
01062 
01063 void* ON_Base64EncodeStream::CallbackContext() const
01064 {
01065   return m_out_callback_context;
01066 }
01067 
01068 ON__UINT64 ON_Base64EncodeStream::InSize() const
01069 {
01070   return m_in_size;
01071 }
01072 
01073 ON__UINT64 ON_Base64EncodeStream::OutSize() const
01074 {
01075   return m_out_size;
01076 }
01077 
01078 ON__UINT32 ON_Base64EncodeStream::InCRC() const
01079 {
01080   return m_in_crc;
01081 }
01082 
01083 ON__UINT32 ON_Base64EncodeStream::OutCRC() const
01084 {
01085   return m_out_crc;
01086 }
01087 
01088 


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:26:59