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