lowlevellibsandfws/apputils/multipartparser/src/qpcodec.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // INCLUDE FILES
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <e32std.h>
       
    19 #include <bafl/qpcodec.h>
       
    20 
       
    21 /**
       
    22 Decode the string
       
    23 @param aSrcString source string
       
    24 @param rDestString Destination string
       
    25 @return  KErrNone  if decode is complete
       
    26 @return  KErrCorrupt if string is not QuotedPrintable compliant
       
    27 */
       
    28 EXPORT_C TInt QuotedPrintableCodec::Decode( const TDesC8& aSrcString, TDes8& rDestString )
       
    29 	{
       
    30 	
       
    31 #ifdef _DEBUG
       
    32 	TInt KPanicInvalidSMTPLine = 6;
       
    33 	_LIT(KDllName,"MultipartParser");
       
    34 #endif
       
    35 	
       
    36 	const TUint8 KImcvSP			= ' ';
       
    37 	const TUint8 KImcvCR			= '\r';
       
    38 	const TUint8 KImcvLF			= '\n';	
       
    39 	const TUint8 KImcvTab			= '\t';
       
    40 	const TUint8 KImcvEquals		= '=';
       
    41 	TUint8 qpCharacter = KImcvEquals;
       
    42 	
       
    43 	TInt error = KErrNone;
       
    44 	
       
    45 	__ASSERT_DEBUG(aSrcString.Length(), User::Panic( KDllName ,KPanicInvalidSMTPLine));
       
    46 
       
    47 	rDestString = KNullDesC8;
       
    48 
       
    49 	TPtrC8 source( aSrcString.Ptr(), aSrcString.Length() );
       
    50 	const TUint8* pSource = source.Ptr();
       
    51 	const TUint8* pEnd = pSource+aSrcString.Length();
       
    52 	
       
    53 	// find out if this is a blank line, if so then we'll add a paragraph delimiter instead
       
    54 	// assume it's blank and then look for non-blank characters
       
    55 	// avoid the CRLF at the end of the line (we know it's there thanks to the assertion above)
       
    56 
       
    57 	TBool blankLine = ETrue; 
       
    58 	while (pSource < pEnd-2) 
       
    59 		{
       
    60 		if (*pSource!=KImcvSP && *pSource!=KImcvTab)
       
    61 			{
       
    62 			blankLine = EFalse;
       
    63 			break;
       
    64 			}
       
    65 		pSource++;
       
    66 		}
       
    67 
       
    68 	if ( blankLine )
       
    69 		{
       
    70 		rDestString.Copy( aSrcString );
       
    71 		return KErrNone;
       
    72 		}
       
    73 
       
    74 	TInt outputLength=0;
       
    75 	TUint8 loBits;
       
    76 	TUint8 hiBits;
       
    77 	TUint8 asciiValue;
       
    78 	pSource = source.Ptr();	// reset to start of source data
       
    79 	const TUint8 zero = '0';
       
    80 	const TUint8 alphaAdjust = 55;  // 'A' is ascii 65 so we need to subtract 55 from 
       
    81 									// alphabetical hex digits to get their numeric value
       
    82 	while( pSource < pEnd )
       
    83 		{
       
    84 		if (*pSource != qpCharacter )
       
    85 			{
       
    86 			//  Quoted character or Attachment bound, just bung it on & move to the next one
       
    87 			// *ptr++ = *pSource;
       
    88 			outputLength++;
       
    89 			rDestString.Append( *pSource );
       
    90 			}
       
    91 		else	// check for encoded character
       
    92 			{
       
    93 			// start looking at the next two characters, if they are there.
       
    94 
       
    95 			if ( pSource+2 < pEnd )
       
    96 				{
       
    97 				pSource++;
       
    98 
       
    99 				// check for '=' at EOL => this is a soft break, so remove it
       
   100 				if (*pSource != KImcvCR) 
       
   101 					{
       
   102 					if(*pSource != KImcvLF) 
       
   103 						{
       
   104 					 	 // now decode hex value into ASCII code : hi-order bits come first
       
   105 						 hiBits = (TUint8)(0x0F & (IsDigit( *pSource ) ? (TUint8)(*pSource-zero) : (TUint8)(*pSource-alphaAdjust)));
       
   106 						 pSource++;
       
   107 						 loBits = (TUint8)(0x0F & (IsDigit( *pSource ) ? (TUint8)(*pSource-zero) : (TUint8)(*pSource-alphaAdjust)));
       
   108 						 asciiValue = (TUint8)( (hiBits<<4) + loBits);
       
   109 						 // bung the character thus formed onto the decoded string
       
   110 						 rDestString.Append( asciiValue );
       
   111 						 // *ptr++ = asciiValue;
       
   112 						 outputLength++;
       
   113 						}
       
   114 					}
       
   115 				else
       
   116 					{
       
   117 					pSource++;
       
   118 					if(*pSource != KImcvLF)
       
   119 						{
       
   120 						error=KErrCorrupt;
       
   121 						pSource-=2;
       
   122 						rDestString.Append( *pSource );
       
   123 						pSource++;
       
   124 						rDestString.Append( *pSource );
       
   125 						pSource++;
       
   126 						outputLength+=2;
       
   127 						}
       
   128 					}
       
   129 				}
       
   130 			else
       
   131 				{
       
   132 				// copy the rest of the data & use up the input string in the process.
       
   133 
       
   134 				while (pSource < pEnd)
       
   135 					{
       
   136 					error=KErrCorrupt; // not QP compliant
       
   137 					//*ptr++ = *pSource++;
       
   138 					outputLength++;
       
   139 					rDestString.Append( *pSource );
       
   140 					pSource++;
       
   141 					}
       
   142 				}
       
   143 			} // check for '=' char
       
   144 		
       
   145 		pSource++;  // next source charactery
       
   146 	} // while
       
   147 
       
   148 	rDestString.SetLength(outputLength);
       
   149 
       
   150 	return error;
       
   151 	}
       
   152 
       
   153 /**
       
   154 Check for digit
       
   155 @param aChar charcter to be check
       
   156 @return  ETrue if passed charcter is digit
       
   157 @return  EFalse if passed charcter is not digit
       
   158 */	
       
   159 TBool QuotedPrintableCodec::IsDigit( TChar aChar )
       
   160 {
       
   161 	return ( (aChar >= '0') && (aChar <= '9') );
       
   162 }