diff -r 000000000000 -r e4d67989cc36 lowlevellibsandfws/apputils/multipartparser/src/qpcodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lowlevellibsandfws/apputils/multipartparser/src/qpcodec.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,162 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// INCLUDE FILES +// +// + +#include +#include + +/** +Decode the string +@param aSrcString source string +@param rDestString Destination string +@return KErrNone if decode is complete +@return KErrCorrupt if string is not QuotedPrintable compliant +*/ +EXPORT_C TInt QuotedPrintableCodec::Decode( const TDesC8& aSrcString, TDes8& rDestString ) + { + +#ifdef _DEBUG + TInt KPanicInvalidSMTPLine = 6; + _LIT(KDllName,"MultipartParser"); +#endif + + const TUint8 KImcvSP = ' '; + const TUint8 KImcvCR = '\r'; + const TUint8 KImcvLF = '\n'; + const TUint8 KImcvTab = '\t'; + const TUint8 KImcvEquals = '='; + TUint8 qpCharacter = KImcvEquals; + + TInt error = KErrNone; + + __ASSERT_DEBUG(aSrcString.Length(), User::Panic( KDllName ,KPanicInvalidSMTPLine)); + + rDestString = KNullDesC8; + + TPtrC8 source( aSrcString.Ptr(), aSrcString.Length() ); + const TUint8* pSource = source.Ptr(); + const TUint8* pEnd = pSource+aSrcString.Length(); + + // find out if this is a blank line, if so then we'll add a paragraph delimiter instead + // assume it's blank and then look for non-blank characters + // avoid the CRLF at the end of the line (we know it's there thanks to the assertion above) + + TBool blankLine = ETrue; + while (pSource < pEnd-2) + { + if (*pSource!=KImcvSP && *pSource!=KImcvTab) + { + blankLine = EFalse; + break; + } + pSource++; + } + + if ( blankLine ) + { + rDestString.Copy( aSrcString ); + return KErrNone; + } + + TInt outputLength=0; + TUint8 loBits; + TUint8 hiBits; + TUint8 asciiValue; + pSource = source.Ptr(); // reset to start of source data + const TUint8 zero = '0'; + const TUint8 alphaAdjust = 55; // 'A' is ascii 65 so we need to subtract 55 from + // alphabetical hex digits to get their numeric value + while( pSource < pEnd ) + { + if (*pSource != qpCharacter ) + { + // Quoted character or Attachment bound, just bung it on & move to the next one + // *ptr++ = *pSource; + outputLength++; + rDestString.Append( *pSource ); + } + else // check for encoded character + { + // start looking at the next two characters, if they are there. + + if ( pSource+2 < pEnd ) + { + pSource++; + + // check for '=' at EOL => this is a soft break, so remove it + if (*pSource != KImcvCR) + { + if(*pSource != KImcvLF) + { + // now decode hex value into ASCII code : hi-order bits come first + hiBits = (TUint8)(0x0F & (IsDigit( *pSource ) ? (TUint8)(*pSource-zero) : (TUint8)(*pSource-alphaAdjust))); + pSource++; + loBits = (TUint8)(0x0F & (IsDigit( *pSource ) ? (TUint8)(*pSource-zero) : (TUint8)(*pSource-alphaAdjust))); + asciiValue = (TUint8)( (hiBits<<4) + loBits); + // bung the character thus formed onto the decoded string + rDestString.Append( asciiValue ); + // *ptr++ = asciiValue; + outputLength++; + } + } + else + { + pSource++; + if(*pSource != KImcvLF) + { + error=KErrCorrupt; + pSource-=2; + rDestString.Append( *pSource ); + pSource++; + rDestString.Append( *pSource ); + pSource++; + outputLength+=2; + } + } + } + else + { + // copy the rest of the data & use up the input string in the process. + + while (pSource < pEnd) + { + error=KErrCorrupt; // not QP compliant + //*ptr++ = *pSource++; + outputLength++; + rDestString.Append( *pSource ); + pSource++; + } + } + } // check for '=' char + + pSource++; // next source charactery + } // while + + rDestString.SetLength(outputLength); + + return error; + } + +/** +Check for digit +@param aChar charcter to be check +@return ETrue if passed charcter is digit +@return EFalse if passed charcter is not digit +*/ +TBool QuotedPrintableCodec::IsDigit( TChar aChar ) +{ + return ( (aChar >= '0') && (aChar <= '9') ); +}