os/ossrv/lowlevellibsandfws/apputils/multipartparser/src/qpcodec.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 }