libkdenetwork Library API Documentation

kmime_codecs.cpp

00001 /*  -*- c++ -*-
00002     kmime_codecs.cpp
00003 
00004     This file is part of KMime, the KDE internet mail/usenet news message library.
00005     Copyright (c) 2001-2002 Marc Mutz <mutz@kde.org>
00006 
00007     KMime is free software; you can redistribute it and/or modify it
00008     under the terms of the GNU General Public License, version 2, as
00009     published by the Free Software Foundation.
00010 
00011     KMime is distributed in the hope that it will be useful, but
00012     WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this library; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020     In addition, as a special exception, the copyright holders give
00021     permission to link the code of this library with any edition of
00022     the Qt library by Trolltech AS, Norway (or with modified versions
00023     of Qt that use the same license as Qt), and distribute linked
00024     combinations including the two.  You must obey the GNU General
00025     Public License in all respects for all of the code used other than
00026     Qt.  If you modify this file, you may extend this exception to
00027     your version of the file, but you are not obligated to do so.  If
00028     you do not wish to do so, delete this exception statement from
00029     your version.
00030 */
00031 
00032 #include "kmime_codecs.h"
00033 #include "kmime_util.h"
00034 
00035 #include "kmime_codec_base64.h"
00036 #include "kmime_codec_qp.h"
00037 #include "kmime_codec_uuencode.h"
00038 #include "kmime_codec_identity.h"
00039 
00040 #include <kdebug.h>
00041 
00042 #include <qcstring.h>
00043 
00044 #include <cassert>
00045 #include <cstring>
00046 
00047 using namespace KMime;
00048 
00049 namespace KMime {
00050 
00051 // global list of KMime::Codec's
00052 QAsciiDict<Codec> Codec::all( 11, false /* case-insensitive */);
00053 #if defined(QT_THREAD_SUPPORT)
00054 QMutex Codec::dictLock;
00055 #endif
00056 
00057 void Codec::fillDictionary() {
00058 
00059   all.setAutoDelete(true);
00060 
00061   //all.insert( "7bit", new SevenBitCodec() );
00062   //all.insert( "8bit", new EightBitCodec() );
00063   all.insert( "base64", new Base64Codec() );
00064   all.insert( "quoted-printable", new QuotedPrintableCodec() );
00065   all.insert( "b", new Rfc2047BEncodingCodec() );
00066   all.insert( "q", new Rfc2047QEncodingCodec() );
00067   all.insert( "x-kmime-rfc2231", new Rfc2231EncodingCodec() );
00068   all.insert( "x-uuencode", new UUCodec() );
00069   //all.insert( "binary", new BinaryCodec() );
00070 
00071 }
00072 
00073 Codec * Codec::codecForName( const char * name ) {
00074 #if defined(QT_THREAD_SUPPORT)
00075   dictLock.lock(); // protect "all"
00076 #endif
00077   if ( all.isEmpty() )
00078     fillDictionary();
00079   Codec * codec = all[ name ];
00080 #if defined(QT_THREAD_SUPPORT)
00081   dictLock.unlock();
00082 #endif
00083 
00084   if ( !codec )
00085     kdDebug() << "Unknown codec \"" << name << "\" requested!" << endl;
00086 
00087   return codec;
00088 }
00089 
00090 Codec * Codec::codecForName( const QCString & name ) {
00091   return codecForName( name.data() );
00092 }
00093 
00094 bool Codec::encode( const char* & scursor, const char * const send,
00095             char* & dcursor, const char * const dend,
00096             bool withCRLF ) const
00097 {
00098   // get an encoder:
00099   Encoder * enc = makeEncoder( withCRLF );
00100   assert( enc );
00101 
00102   // encode and check for output buffer overflow:
00103   while ( !enc->encode( scursor, send, dcursor, dend ) )
00104     if ( dcursor == dend ) {
00105       delete enc;
00106       return false; // not enough space in output buffer
00107     }
00108 
00109   // finish and check for output buffer overflow:
00110   while ( !enc->finish( dcursor, dend ) )
00111     if ( dcursor == dend ) {
00112       delete enc;
00113       return false; // not enough space in output buffer
00114     }
00115 
00116   // cleanup and return:
00117   delete enc;
00118   return true; // successfully encoded.
00119 }
00120 
00121 QByteArray Codec::encode( const QByteArray & src, bool withCRLF ) const
00122 {
00123   // allocate buffer for the worst case:
00124   QByteArray result( maxEncodedSizeFor( src.size(), withCRLF ) );
00125 
00126   // set up iterators:
00127   QByteArray::ConstIterator iit = src.begin();
00128   QByteArray::ConstIterator iend = src.end();
00129   QByteArray::Iterator oit = result.begin();
00130   QByteArray::ConstIterator oend = result.end();
00131 
00132   // encode
00133   if ( !encode( iit, iend, oit, oend, withCRLF ) )
00134     kdFatal() << name() << " codec lies about it's mEncodedSizeFor()"
00135           << endl;
00136 
00137   // shrink result to actual size:
00138   result.truncate( oit - result.begin() );
00139 
00140   return result;
00141 }
00142 
00143 QCString Codec::encodeToQCString( const QByteArray & src, bool withCRLF ) const
00144 {
00145   // allocate buffer for the worst case (remember to add one for the trailing NUL)
00146   QCString result( maxEncodedSizeFor( src.size(), withCRLF ) + 1 );
00147 
00148   // set up iterators:
00149   QByteArray::ConstIterator iit = src.begin();
00150   QByteArray::ConstIterator iend = src.end();
00151   QByteArray::Iterator oit = result.begin();
00152   QByteArray::ConstIterator oend = result.end() - 1;
00153 
00154   // encode
00155   if ( !encode( iit, iend, oit, oend, withCRLF ) )
00156     kdFatal() << name() << " codec lies about it's mEncodedSizeFor()"
00157           << endl;
00158 
00159   // shrink result to actual size:
00160   result.truncate( oit - result.begin() );
00161 
00162   return result;
00163 }
00164 
00165 QByteArray Codec::decode( const QByteArray & src, bool withCRLF ) const
00166 {
00167   // allocate buffer for the worst case:
00168   QByteArray result( maxDecodedSizeFor( src.size(), withCRLF ) );
00169 
00170   // set up iterators:
00171   QByteArray::ConstIterator iit = src.begin();
00172   QByteArray::ConstIterator iend = src.end();
00173   QByteArray::Iterator oit = result.begin();
00174   QByteArray::ConstIterator oend = result.end();
00175 
00176   // decode
00177   if ( !decode( iit, iend, oit, oend, withCRLF ) )
00178     kdFatal() << name() << " codec lies about it's maxDecodedSizeFor()"
00179           << endl;
00180 
00181   // shrink result to actual size:
00182   result.truncate( oit - result.begin() );
00183 
00184   return result;
00185 }
00186 
00187 bool Codec::decode( const char* & scursor, const char * const send,
00188             char* & dcursor, const char * const dend,
00189             bool withCRLF ) const
00190 {
00191   // get a decoder:
00192   Decoder * dec = makeDecoder( withCRLF );
00193   assert( dec );
00194 
00195   // decode and check for output buffer overflow:
00196   while ( !dec->decode( scursor, send, dcursor, dend ) )
00197     if ( dcursor == dend ) {
00198       delete dec;
00199       return false; // not enough space in output buffer
00200     }
00201 
00202   // finish and check for output buffer overflow:
00203   while ( !dec->finish( dcursor, dend ) )
00204     if ( dcursor == dend ) {
00205       delete dec;
00206       return false; // not enough space in output buffer
00207     }
00208 
00209   // cleanup and return:
00210   delete dec;
00211   return true; // successfully encoded.
00212 }
00213 
00214 // write as much as possible off the output buffer. Return true if
00215 // flushing was complete, false if some chars could not be flushed.
00216 bool Encoder::flushOutputBuffer( char* & dcursor, const char * const dend ) {
00217   int i;
00218   // copy output buffer to output stream:
00219   for ( i = 0 ; dcursor != dend && i < mOutputBufferCursor ; ++i )
00220     *dcursor++ = mOutputBuffer[i];
00221 
00222   // calculate the number of missing chars:
00223   int numCharsLeft = mOutputBufferCursor - i;
00224   // push the remaining chars to the begin of the buffer:
00225   if ( numCharsLeft )
00226     qmemmove( mOutputBuffer, mOutputBuffer + i, numCharsLeft );
00227   // adjust cursor:
00228   mOutputBufferCursor = numCharsLeft;
00229 
00230   return !numCharsLeft;
00231 }
00232 
00233 
00234 } // namespace KMime
KDE Logo
This file is part of the documentation for libkdenetwork Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu May 3 20:16:59 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003