• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

KMIME Library

kmime_codecs.cpp
Go to the documentation of this file.
00001 /*  -*- c++ -*-
00002 
00003     KMime, the KDE Internet mail/usenet news message library.
00004 
00005     Copyright (c) 2001-2002 Marc Mutz <mutz@kde.org>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00033 #include "kmime_codecs.h"
00034 #include "kmime_util.h"
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 "kautodeletehash.h"
00041 
00042 #include <kascii.h>
00043 #include <kdebug.h>
00044 #include <kglobal.h>
00045 
00046 #include <QtCore/QCoreApplication>
00047 #include <QtCore/QMutex>
00048 
00049 #include <cassert>
00050 #include <cstring>
00051 #include <string.h>
00052 
00053 using namespace KMime;
00054 
00055 namespace KMime {
00056 
00057 // global list of KMime::Codec's
00058 //@cond PRIVATE
00059 KAutoDeleteHash<QByteArray, Codec> *Codec::all = 0;
00060 K_GLOBAL_STATIC(QMutex, dictLock)
00061 //@endcond
00062 
00063 void Codec::cleanupCodec()
00064 {
00065     delete all;
00066     all = 0;
00067 }
00068 
00069 void Codec::fillDictionary()
00070 {
00071   //all->insert( "7bit", new SevenBitCodec() );
00072   //all->insert( "8bit", new EightBitCodec() );
00073   all->insert( "base64", new Base64Codec() );
00074   all->insert( "quoted-printable", new QuotedPrintableCodec() );
00075   all->insert( "b", new Rfc2047BEncodingCodec() );
00076   all->insert( "q", new Rfc2047QEncodingCodec() );
00077   all->insert( "x-kmime-rfc2231", new Rfc2231EncodingCodec() );
00078   all->insert( "x-uuencode", new UUCodec() );
00079   //all->insert( "binary", new BinaryCodec() );
00080 }
00081 
00082 Codec *Codec::codecForName( const char *name )
00083 {
00084   const QByteArray ba( name );
00085   return codecForName( ba );
00086 }
00087 
00088 Codec *Codec::codecForName( const QByteArray &name )
00089 {
00090   dictLock->lock(); // protect "all"
00091   if ( !all ) {
00092     all = new KAutoDeleteHash<QByteArray, Codec>();
00093     qAddPostRoutine(cleanupCodec);
00094     fillDictionary();
00095   }
00096   QByteArray lowerName = name;
00097   kAsciiToLower( lowerName.data() );
00098   Codec *codec = (*all)[ lowerName ]; // FIXME: operator[] adds an entry into the hash
00099   dictLock->unlock();
00100 
00101   if ( !codec ) {
00102     kDebug() << "Unknown codec \"" << name << "\" requested!";
00103   }
00104 
00105   return codec;
00106 }
00107 
00108 bool Codec::encode( const char* &scursor, const char * const send,
00109                     char* &dcursor, const char * const dend,
00110                     bool withCRLF ) const
00111 {
00112   // get an encoder:
00113   Encoder *enc = makeEncoder( withCRLF );
00114   assert( enc );
00115 
00116   // encode and check for output buffer overflow:
00117   while ( !enc->encode( scursor, send, dcursor, dend ) ) {
00118     if ( dcursor == dend ) {
00119       delete enc;
00120       return false; // not enough space in output buffer
00121     }
00122   }
00123 
00124   // finish and check for output buffer overflow:
00125   while ( !enc->finish( dcursor, dend ) ) {
00126     if ( dcursor == dend ) {
00127       delete enc;
00128       return false; // not enough space in output buffer
00129     }
00130   }
00131 
00132   // cleanup and return:
00133   delete enc;
00134   return true; // successfully encoded.
00135 }
00136 
00137 QByteArray Codec::encode( const QByteArray &src, bool withCRLF ) const
00138 {
00139   // allocate buffer for the worst case:
00140   QByteArray result;
00141   result.resize( maxEncodedSizeFor( src.size(), withCRLF ) );
00142 
00143   // set up iterators:
00144   QByteArray::ConstIterator iit = src.begin();
00145   QByteArray::ConstIterator iend = src.end();
00146   QByteArray::Iterator oit = result.begin();
00147   QByteArray::ConstIterator oend = result.end();
00148 
00149   // encode
00150   if ( !encode( iit, iend, oit, oend, withCRLF ) ) {
00151     kFatal() << name() << "codec lies about it's mEncodedSizeFor()";
00152   }
00153 
00154   // shrink result to actual size:
00155   result.truncate( oit - result.begin() );
00156 
00157   return result;
00158 }
00159 
00160 QByteArray Codec::decode( const QByteArray &src, bool withCRLF ) const
00161 {
00162   // allocate buffer for the worst case:
00163   QByteArray result;
00164   result.resize( maxDecodedSizeFor( src.size(), withCRLF ) );
00165 
00166   // set up iterators:
00167   QByteArray::ConstIterator iit = src.begin();
00168   QByteArray::ConstIterator iend = src.end();
00169   QByteArray::Iterator oit = result.begin();
00170   QByteArray::ConstIterator oend = result.end();
00171 
00172   // decode
00173   if ( !decode( iit, iend, oit, oend, withCRLF ) ) {
00174     kFatal() << name() << "codec lies about it's maxDecodedSizeFor()";
00175   }
00176 
00177   // shrink result to actual size:
00178   result.truncate( oit - result.begin() );
00179 
00180   return result;
00181 }
00182 
00183 bool Codec::decode( const char* &scursor, const char * const send,
00184                     char* &dcursor, const char * const dend,
00185                     bool withCRLF ) const
00186 {
00187   // get a decoder:
00188   Decoder *dec = makeDecoder( withCRLF );
00189   assert( dec );
00190 
00191   // decode and check for output buffer overflow:
00192   while ( !dec->decode( scursor, send, dcursor, dend ) ) {
00193     if ( dcursor == dend ) {
00194       delete dec;
00195       return false; // not enough space in output buffer
00196     }
00197   }
00198 
00199   // finish and check for output buffer overflow:
00200   while ( !dec->finish( dcursor, dend ) ) {
00201     if ( dcursor == dend ) {
00202       delete dec;
00203       return false; // not enough space in output buffer
00204     }
00205   }
00206 
00207   // cleanup and return:
00208   delete dec;
00209   return true; // successfully encoded.
00210 }
00211 
00212 // write as much as possible off the output buffer. Return true if
00213 // flushing was complete, false if some chars could not be flushed.
00214 bool Encoder::flushOutputBuffer( char* &dcursor, const char * const dend )
00215 {
00216   int i;
00217   // copy output buffer to output stream:
00218   for ( i = 0 ; dcursor != dend && i < mOutputBufferCursor ; ++i ) {
00219     *dcursor++ = mOutputBuffer[i];
00220   }
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     ::memmove( mOutputBuffer, mOutputBuffer + i, numCharsLeft );
00227   }
00228   // adjust cursor:
00229   mOutputBufferCursor = numCharsLeft;
00230 
00231   return !numCharsLeft;
00232 }
00233 
00234 } // namespace KMime
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:17:28 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KMIME Library

Skip menu "KMIME Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal