39 using namespace KMime;
 
   54 static const uchar base64DecodeMap[128] = {
 
   55   64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
 
   56   64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,
 
   58   64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 62, 64, 64, 64, 63,
 
   59   52, 53, 54, 55, 56, 57, 58, 59,  60, 61, 64, 64, 64, 64, 64, 64,
 
   61   64,  0,  1,  2,  3,  4,  5,  6,   7,  8,  9, 10, 11, 12, 13, 14,
 
   62   15, 16, 17, 18, 19, 20, 21, 22,  23, 24, 25, 64, 64, 64, 64, 64,
 
   64   64, 26, 27, 28, 29, 30, 31, 32,  33, 34, 35, 36, 37, 38, 39, 40,
 
   65   41, 42, 43, 44, 45, 46, 47, 48,  49, 50, 51, 64, 64, 64, 64, 64
 
   68 static const char base64EncodeMap[64] = {
 
   69   'A', 
'B', 
'C', 
'D', 
'E', 
'F', 
'G', 
'H',
 
   70   'I', 
'J', 
'K', 
'L', 
'M', 
'N', 
'O', 
'P',
 
   71   'Q', 
'R', 
'S', 
'T', 
'U', 
'V', 
'W', 
'X',
 
   72   'Y', 
'Z', 
'a', 
'b', 
'c', 
'd', 
'e', 
'f',
 
   73   'g', 
'h', 
'i', 
'j', 
'k', 
'l', 
'm', 
'n',
 
   74   'o', 
'p', 
'q', 
'r', 
's', 
't', 
'u', 
'v',
 
   75   'w', 
'x', 
'y', 
'z', 
'0', 
'1', 
'2', 
'3',
 
   76   '4', 
'5', 
'6', 
'7', 
'8', 
'9', 
'+', 
'/' 
   80 class Base64Decoder : 
public Decoder 
   88     Base64Decoder( 
bool withCRLF=
false )
 
   89       : 
Decoder( withCRLF ), mStepNo( 0 ), mOutbits( 0 ),
 
   90         mSawPadding( false ) {}
 
   93     virtual ~Base64Decoder() {}
 
   95     bool decode( 
const char* &scursor, 
const char * 
const send,
 
   96                  char* &dcursor, 
const char * 
const dend );
 
   98     bool finish( 
char* &dcursor, 
const char * 
const dend )
 
  100         Q_UNUSED( dcursor ); Q_UNUSED( dend );
 
  105 class Base64Encoder : 
public Encoder 
  109   uint mWrittenPacketsOnThisLine;
 
  111   bool mInsideFinishing : 1;
 
  115     friend class Rfc2047BEncodingEncoder;
 
  117     Base64Encoder( 
bool withCRLF=
false )
 
  118       : 
Encoder( withCRLF ), mStepNo( 0 ), mWrittenPacketsOnThisLine( 0 ),
 
  119         mNextbits( 0 ), mInsideFinishing( false ) {}
 
  121     bool generic_finish( 
char* &dcursor, 
const char * 
const dend,
 
  125     virtual ~Base64Encoder() {}
 
  127     bool encode( 
const char* &scursor, 
const char * 
const send,
 
  128                  char* &dcursor, 
const char * 
const dend );
 
  130     bool finish( 
char* &dcursor, 
const char * 
const dend );
 
  133     bool writeBase64( uchar ch, 
char* &dcursor, 
const char * 
const dend )
 
  134       { 
return write( base64EncodeMap[ ch ], dcursor, dend ); }
 
  137 class Rfc2047BEncodingEncoder : 
public Base64Encoder
 
  141     Rfc2047BEncodingEncoder( 
bool withCRLF=
false )
 
  142       : Base64Encoder( withCRLF ) {}
 
  145     bool encode( 
const char* &scursor, 
const char * 
const send,
 
  146                  char* &dcursor, 
const char * 
const dend );
 
  147     bool finish( 
char* &dcursor, 
const char * 
const dend );
 
  152   return new Base64Encoder( withCRLF );
 
  157   return new Base64Decoder( withCRLF );
 
  162   return new Rfc2047BEncodingEncoder( withCRLF );
 
  169 bool Base64Decoder::decode( 
const char* &scursor, 
const char * 
const send,
 
  170                             char* &dcursor, 
const char * 
const dend )
 
  172   while ( dcursor != dend && scursor != send ) {
 
  173     uchar ch = *scursor++;
 
  178       value = base64DecodeMap[ ch ];
 
  187         if ( mStepNo == 0 || mStepNo == 1 ) {
 
  188           if ( !mSawPadding ) {
 
  190             kWarning() << 
"Base64Decoder: unexpected padding" 
  191               "character in input stream";
 
  195         } 
else if ( mStepNo == 2 ) {
 
  197         } 
else if ( mStepNo == 3 ) {
 
  203         mStepNo = ( mStepNo + 1 ) % 4;
 
  212       kWarning() << 
"Base64Decoder: Embedded padding character" 
  220       mOutbits = value << 2;
 
  223       *dcursor++ = (char)( mOutbits | value >> 4 );
 
  224       mOutbits = value << 4;
 
  227       *dcursor++ = (char)( mOutbits | value >> 2 );
 
  228       mOutbits = value << 6;
 
  231       *dcursor++ = (char)( mOutbits | value );
 
  237     mStepNo = ( mStepNo + 1 ) % 4;
 
  241   return scursor == send;
 
  244 bool Base64Encoder::encode( 
const char* &scursor, 
const char * 
const send,
 
  245                             char* &dcursor, 
const char * 
const dend )
 
  247   const uint maxPacketsPerLine = 76 / 4;
 
  250   if ( mInsideFinishing ) {
 
  254   while ( scursor != send && dcursor != dend ) {
 
  258     if ( mOutputBufferCursor && !flushOutputBuffer( dcursor, dend ) ) {
 
  259       return scursor == send;
 
  262     uchar ch = *scursor++;
 
  266     if ( mStepNo == 0 && mWrittenPacketsOnThisLine >= maxPacketsPerLine ) {
 
  267       writeCRLF( dcursor, dend );
 
  268       mWrittenPacketsOnThisLine = 0;
 
  275       assert( mNextbits == 0 );
 
  276       writeBase64( ch >> 2, dcursor, dend ); 
 
  277       mNextbits = ( ch & 0x3 ) << 4; 
 
  280       assert( ( mNextbits & ~0x30 ) == 0 );
 
  281       writeBase64( mNextbits | ch >> 4, dcursor, dend ); 
 
  282       mNextbits = ( ch & 0xf ) << 2; 
 
  285       assert( ( mNextbits & ~0x3C ) == 0 );
 
  286       writeBase64( mNextbits | ch >> 6, dcursor, dend ); 
 
  287       writeBase64( ch & 0x3F, dcursor, dend ); 
 
  289       mWrittenPacketsOnThisLine++;
 
  294     mStepNo = ( mStepNo + 1 ) % 3;
 
  297   if ( mOutputBufferCursor ) {
 
  298     flushOutputBuffer( dcursor, dend );
 
  301   return scursor == send;
 
  304 bool Rfc2047BEncodingEncoder::encode( 
const char* &scursor,
 
  305                                       const char * 
const send,
 
  307                                       const char * 
const dend )
 
  310   if ( mInsideFinishing ) {
 
  314   while ( scursor != send && dcursor != dend ) {
 
  318     if ( mOutputBufferCursor && !flushOutputBuffer( dcursor, dend ) ) {
 
  319       return scursor == send;
 
  322     uchar ch = *scursor++;
 
  329       assert( mNextbits == 0 );
 
  330       writeBase64( ch >> 2, dcursor, dend ); 
 
  331       mNextbits = ( ch & 0x3 ) << 4; 
 
  334       assert( ( mNextbits & ~0x30 ) == 0 );
 
  335       writeBase64( mNextbits | ch >> 4, dcursor, dend ); 
 
  336       mNextbits = ( ch & 0xf ) << 2; 
 
  339       assert( ( mNextbits & ~0x3C ) == 0 );
 
  340       writeBase64( mNextbits | ch >> 6, dcursor, dend ); 
 
  341       writeBase64( ch & 0x3F, dcursor, dend ); 
 
  347     mStepNo = ( mStepNo + 1 ) % 3;
 
  350   if ( mOutputBufferCursor ) {
 
  351     flushOutputBuffer( dcursor, dend );
 
  354   return scursor == send;
 
  357 bool Base64Encoder::finish( 
char* &dcursor, 
const char * 
const dend )
 
  359   return generic_finish( dcursor, dend, 
true );
 
  362 bool Rfc2047BEncodingEncoder::finish( 
char* & dcursor,
 
  363                                       const char * 
const dend )
 
  365   return generic_finish( dcursor, dend, 
false );
 
  368 bool Base64Encoder::generic_finish( 
char* &dcursor, 
const char * 
const dend,
 
  371   if ( mInsideFinishing ) {
 
  372     return flushOutputBuffer( dcursor, dend );
 
  375   if ( mOutputBufferCursor && !flushOutputBuffer( dcursor, dend ) ) {
 
  379   mInsideFinishing = 
true;
 
  387     writeBase64( mNextbits, dcursor, dend );
 
  391     assert( mNextbits == 0 );
 
  402     write( 
'=', dcursor, dend );
 
  405     write( 
'=', dcursor, dend );
 
  409       writeCRLF( dcursor, dend );
 
  411     return flushOutputBuffer( dcursor, dend );
 
Encoder * makeEncoder(bool withCRLF=false) const 
 
This file is part of the API for handling MIME data and defines the Base64 and RFC2047B Codec classes...
 
Decoder * makeDecoder(bool withCRLF=false) const 
 
A class representing the codec for Base64 as specified in RFC2045. 
 
Stateful CTE decoder class. 
 
bool write(char ch, char *&dcursor, const char *const dend)
Writes character ch to the output stream or the output buffer, depending on whether or not the output...
 
Encoder * makeEncoder(bool withCRLF=false) const 
 
A class representing the codec for the B encoding as specified in RFC2047B.