genericservices/httputils/Authentication/TConvBase64.cpp
changeset 0 e4d67989cc36
child 27 3a7375419266
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2006-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 // TBase64.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <tconvbase64.h>
       
    19 
       
    20 /**
       
    21 TBase64 constructor
       
    22 */
       
    23 EXPORT_C TBase64::TBase64(): iShiftStored(0), iMaskShiftStored(ESix)
       
    24 	{}
       
    25 	
       
    26 	
       
    27 /**
       
    28 	Encodes an ASCII string to Base64 string.
       
    29 
       
    30 	@param aSrcString The source string in ASCII code.
       
    31 	@param rDestString The destination string with converted base64 values.
       
    32 	@return Number of characters in the source string that were not Encoded.
       
    33 */	
       
    34 EXPORT_C TInt TBase64::Encode(const TDesC8& aSrcString, TDes8& rDestString)
       
    35 	{
       
    36     // Clears the destination string
       
    37     rDestString.Zero();
       
    38     // Initialise variables
       
    39     const TUint8* srcStringPtr=aSrcString.Ptr();
       
    40     const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr;
       
    41     TUint8* destStringPtr=(TUint8*)rDestString.Ptr();
       
    42     TUint8* destStringPtrBase=destStringPtr;
       
    43     TInt character=0;
       
    44     TUint8 encodedChar=0;
       
    45     TInt charStorage=0;
       
    46     TInt maskShift=EZero;
       
    47     TInt destStringCharNum = 0;
       
    48 
       
    49     while(srcStringPtr<=srcStringEnd)
       
    50 	    {
       
    51         // maskShift is used as a char read counter
       
    52 	    if(maskShift==ESix)
       
    53             {
       
    54 	        // If the 3rd char read is also the last char then the while loop
       
    55             // is broken on the next check.
       
    56             if(srcStringPtr==srcStringEnd)
       
    57             	srcStringPtr++;
       
    58             maskShift=EZero;
       
    59             character=0;   
       
    60             }
       
    61         else
       
    62             {
       
    63             if(srcStringPtr==srcStringEnd)
       
    64 	            character=0;
       
    65             else
       
    66 		        character=*srcStringPtr;
       
    67  
       
    68 			srcStringPtr++;
       
    69 		    // Shifts charStorage ready for the next char
       
    70 	        charStorage=charStorage<<8;
       
    71             maskShift+=ETwo;
       
    72             }
       
    73         charStorage=charStorage|character;
       
    74         // Shifts the mask to the correct bit location
       
    75         // Masks (AND's) the valid bits from charStorage
       
    76         // Shifts the valid bits into the low order 8bits
       
    77         // Converts to BASE64 char, Casts the result to an unsigned char (which it should be ?....I hope)
       
    78         encodedChar=(TUint8)Base64ToAscii[((charStorage>>maskShift)&ESixBitMask)];
       
    79 
       
    80         *destStringPtr++=encodedChar;
       
    81         destStringCharNum++;
       
    82 
       
    83         // Add a CRLF every KMaxB64EncodedCharsPerLine characters so as not to exceed the line length
       
    84         // limitation specified in RFC 2822.
       
    85         if (destStringCharNum == KMaxB64EncodedCharsPerLine)
       
    86 	        {
       
    87             destStringCharNum = 0;
       
    88             *destStringPtr++ = '\r';
       
    89             *destStringPtr++ = '\n';
       
    90             }
       
    91 		}
       
    92      
       
    93     // Check for not enough chars and pad if required
       
    94     if (maskShift==EFour)
       
    95 	    {
       
    96         *destStringPtr++=KImcvConvEquals;
       
    97         *destStringPtr++=KImcvConvEquals;
       
    98         }
       
    99     else
       
   100         if(maskShift==ESix)
       
   101 	        *destStringPtr++=KImcvConvEquals;   
       
   102             
       
   103     rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
       
   104     return ((TInt)(srcStringPtr-srcStringEnd));
       
   105 	}
       
   106 
       
   107 /**
       
   108 	Decodes the Base64 string to ASCII pattern.
       
   109 
       
   110 	@param aSrcString The source string in Base64 codeset.
       
   111 	@param rDestString The destination string with converted ASCII code values.
       
   112 	@return ETrue if aSrcString is not long enough to decode fully, resulting in the storage of
       
   113 		the last character and requiring another aSrcString (poss 0 length) to be passed to it to clear this character. 
       
   114 		Returns EFalse if the line was decoded OK or the end of the encoded file is reached ie "="
       
   115 */	
       
   116 EXPORT_C TBool TBase64::Decode(const TDesC8& aSrcString, TDes8& rDestString)
       
   117 	{
       
   118 	TInt decodedInt=0;
       
   119 	TInt8 offsetChar=0;
       
   120 	TUint8 decodedChar=0;
       
   121 	 
       
   122 	// Clears the destination string
       
   123 	rDestString.Zero();
       
   124 
       
   125 	// Initialise variables
       
   126 	const TUint8* srcStringPtr=aSrcString.Ptr();
       
   127 	const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr;
       
   128 	TUint8* destStringPtr=(TUint8*)rDestString.Ptr();
       
   129 	TUint8* destStringPtrBase=destStringPtr;
       
   130 
       
   131 	TInt maskShift=iMaskShiftStored;
       
   132 	TInt shiftStorage=iShiftStored;
       
   133 	
       
   134 	// Main character process loop
       
   135 	while(srcStringPtr<srcStringEnd)	
       
   136 		{
       
   137 		offsetChar=(TInt8)(*srcStringPtr-KImcvLookUpStartOffset);
       
   138 		srcStringPtr++;
       
   139 
       
   140 		// Check for valid B64 character		
       
   141 		if((offsetChar>=0)&&(offsetChar<80))
       
   142 			{
       
   143 			// Read in next character and B64 decode
       
   144 			decodedInt=AsciiToBase64[offsetChar];
       
   145 
       
   146 			// Exits when a PAD char is reached
       
   147 			if(decodedInt==EPadChar)
       
   148 				{
       
   149 				rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
       
   150 				return EFalse;
       
   151 				}
       
   152 
       
   153 			// Ensures the first 2 chars of 4 are received before processing
       
   154 			if(maskShift==ESix)
       
   155 				maskShift=EFour;
       
   156 			else
       
   157 				{
       
   158 				shiftStorage=shiftStorage<<ESix;
       
   159 				shiftStorage=shiftStorage|decodedInt;
       
   160 				decodedChar=(TUint8)((shiftStorage>>maskShift)&EEightBitMask);
       
   161 				
       
   162 				if((maskShift-=ETwo)<EZero)
       
   163 					maskShift=ESix; 
       
   164 				
       
   165 				*destStringPtr++=decodedChar;
       
   166 				}
       
   167 			shiftStorage=decodedInt;
       
   168 			}
       
   169 		}
       
   170 	iShiftStored=shiftStorage;
       
   171 	iMaskShiftStored=maskShift;
       
   172 	
       
   173 	rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
       
   174 	
       
   175 	return maskShift<ESix;
       
   176 	}