1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericservices/httputils/Authentication/TConvBase64.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,259 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// TBase64.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <tconvbase64.h>
1.22 +
1.23 +/**
1.24 +TBase64 constructor
1.25 +*/
1.26 +EXPORT_C TBase64::TBase64(): iShiftStored(0), iMaskShiftStored(ESix)
1.27 + {}
1.28 +
1.29 +
1.30 +/**
1.31 + Encodes an ASCII string to Base64 string.
1.32 +
1.33 + @param aSrcString The source string in ASCII code.
1.34 + @param rDestString The destination string with converted base64 values.
1.35 + @return Number of characters in the source string that were not Encoded.
1.36 +*/
1.37 +EXPORT_C TInt TBase64::Encode(const TDesC8& aSrcString, TDes8& rDestString)
1.38 + {
1.39 + // Clears the destination string
1.40 + rDestString.Zero();
1.41 + // Initialise variables
1.42 + const TUint8* srcStringPtr=aSrcString.Ptr();
1.43 + const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr;
1.44 + TUint8* destStringPtr=(TUint8*)rDestString.Ptr();
1.45 + TUint8* destStringPtrBase=destStringPtr;
1.46 + TInt character=0;
1.47 + TUint8 encodedChar=0;
1.48 + TInt charStorage=0;
1.49 + TInt maskShift=EZero;
1.50 + TInt destStringCharNum = 0;
1.51 +
1.52 + while(srcStringPtr<=srcStringEnd)
1.53 + {
1.54 + // maskShift is used as a char read counter
1.55 + if(maskShift==ESix)
1.56 + {
1.57 + // If the 3rd char read is also the last char then the while loop
1.58 + // is broken on the next check.
1.59 + if(srcStringPtr==srcStringEnd)
1.60 + srcStringPtr++;
1.61 + maskShift=EZero;
1.62 + character=0;
1.63 + }
1.64 + else
1.65 + {
1.66 + if(srcStringPtr==srcStringEnd)
1.67 + character=0;
1.68 + else
1.69 + character=*srcStringPtr;
1.70 +
1.71 + srcStringPtr++;
1.72 + // Shifts charStorage ready for the next char
1.73 + charStorage=charStorage<<8;
1.74 + maskShift+=ETwo;
1.75 + }
1.76 + charStorage=charStorage|character;
1.77 + // Shifts the mask to the correct bit location
1.78 + // Masks (AND's) the valid bits from charStorage
1.79 + // Shifts the valid bits into the low order 8bits
1.80 + // Converts to BASE64 char, Casts the result to an unsigned char (which it should be ?....I hope)
1.81 + encodedChar=(TUint8)Base64ToAscii[((charStorage>>maskShift)&ESixBitMask)];
1.82 +
1.83 + *destStringPtr++=encodedChar;
1.84 + destStringCharNum++;
1.85 +
1.86 + // Add a CRLF every KMaxB64EncodedCharsPerLine characters so as not to exceed the line length
1.87 + // limitation specified in RFC 2822.
1.88 + if (destStringCharNum == KMaxB64EncodedCharsPerLine)
1.89 + {
1.90 + destStringCharNum = 0;
1.91 + *destStringPtr++ = '\r';
1.92 + *destStringPtr++ = '\n';
1.93 + }
1.94 + }
1.95 +
1.96 + // Check for not enough chars and pad if required
1.97 + if (maskShift==EFour)
1.98 + {
1.99 + *destStringPtr++=KImcvConvEquals;
1.100 + *destStringPtr++=KImcvConvEquals;
1.101 + }
1.102 + else
1.103 + if(maskShift==ESix)
1.104 + *destStringPtr++=KImcvConvEquals;
1.105 +
1.106 + rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
1.107 + return ((TInt)(srcStringPtr-srcStringEnd));
1.108 + }
1.109 +
1.110 +/**
1.111 + Decodes the Base64 string to ASCII pattern.
1.112 +
1.113 + @param aSrcString The source string in Base64 codeset.
1.114 + @param rDestString The destination string with converted ASCII code values.
1.115 + @return ETrue if aSrcString is not long enough to decode fully, resulting in the storage of
1.116 + the last character and requiring another aSrcString (poss 0 length) to be passed to it to clear this character.
1.117 + Returns EFalse if the line was decoded OK or the end of the encoded file is reached ie "="
1.118 +*/
1.119 +EXPORT_C TBool TBase64::Decode(const TDesC8& aSrcString, TDes8& rDestString)
1.120 + {
1.121 + TInt decodedInt=0;
1.122 + TInt8 offsetChar=0;
1.123 + TUint8 decodedChar=0;
1.124 +
1.125 + // Clears the destination string
1.126 + rDestString.Zero();
1.127 +
1.128 + // Initialise variables
1.129 + const TUint8* srcStringPtr=aSrcString.Ptr();
1.130 + const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr;
1.131 + TUint8* destStringPtr=(TUint8*)rDestString.Ptr();
1.132 + TUint8* destStringPtrBase=destStringPtr;
1.133 +
1.134 + TInt maskShift=iMaskShiftStored;
1.135 + TInt shiftStorage=iShiftStored;
1.136 +
1.137 + // Main character process loop
1.138 + while(srcStringPtr<srcStringEnd)
1.139 + {
1.140 + offsetChar=(TInt8)(*srcStringPtr-KImcvLookUpStartOffset);
1.141 + srcStringPtr++;
1.142 +
1.143 + // Check for valid B64 character
1.144 + if((offsetChar>=0)&&(offsetChar<80))
1.145 + {
1.146 + // Read in next character and B64 decode
1.147 + decodedInt=AsciiToBase64[offsetChar];
1.148 +
1.149 + // Exits when a PAD char is reached
1.150 + if(decodedInt==EPadChar)
1.151 + {
1.152 + rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
1.153 + return EFalse;
1.154 + }
1.155 +
1.156 + // Ensures the first 2 chars of 4 are received before processing
1.157 + if(maskShift==ESix)
1.158 + maskShift=EFour;
1.159 + else
1.160 + {
1.161 + shiftStorage=shiftStorage<<ESix;
1.162 + shiftStorage=shiftStorage|decodedInt;
1.163 + decodedChar=(TUint8)((shiftStorage>>maskShift)&EEightBitMask);
1.164 +
1.165 + if((maskShift-=ETwo)<EZero)
1.166 + maskShift=ESix;
1.167 +
1.168 + *destStringPtr++=decodedChar;
1.169 + }
1.170 + shiftStorage=decodedInt;
1.171 + }
1.172 + }
1.173 + iShiftStored=shiftStorage;
1.174 + iMaskShiftStored=maskShift;
1.175 +
1.176 + rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
1.177 +
1.178 + return maskShift<ESix;
1.179 + }
1.180 +
1.181 +
1.182 +/**
1.183 + Encodes an ASCII string to Base64 string.
1.184 +
1.185 + @param aSrcString The source string in ASCII.
1.186 + @param aDestString The destination string with converted base64 values.
1.187 + @param aLineLength The maximum line length of the encoded base64 values.
1.188 + A CR/LF sequence will be added after these many characters.
1.189 + The default value is -1, which means no CR/LF is added to output. The encoding is compliant with RFC 4648
1.190 + @return Number of characters in the source string that were not encoded.
1.191 +*/
1.192 +EXPORT_C TInt TBase64::PortableEncode(const TDesC8& aSrcString, TDes8& aDestString, TInt aLineLength)
1.193 + {
1.194 + // Clears the destination string
1.195 + aDestString.Zero();
1.196 + // Initialise variables
1.197 + const TUint8* srcStringPtr=aSrcString.Ptr();
1.198 + const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr;
1.199 + TUint8* destStringPtr=(TUint8*)aDestString.Ptr();
1.200 + TUint8* destStringPtrBase=destStringPtr;
1.201 + TInt character=0;
1.202 + TUint8 encodedChar=0;
1.203 + TInt charStorage=0;
1.204 + TInt maskShift=EZero;
1.205 + TInt destStringCharNum = 0;
1.206 +
1.207 + while(srcStringPtr<=srcStringEnd)
1.208 + {
1.209 + // maskShift is used as a char read counter
1.210 + if(maskShift==ESix)
1.211 + {
1.212 + // If the 3rd char read is also the last char then the while loop
1.213 + // is broken on the next check.
1.214 + if(srcStringPtr==srcStringEnd)
1.215 + srcStringPtr++;
1.216 + maskShift=EZero;
1.217 + character=0;
1.218 + }
1.219 + else
1.220 + {
1.221 + if(srcStringPtr==srcStringEnd)
1.222 + character=0;
1.223 + else
1.224 + character=*srcStringPtr;
1.225 +
1.226 + srcStringPtr++;
1.227 + // Shifts charStorage ready for the next char
1.228 + charStorage=charStorage<<8;
1.229 + maskShift+=ETwo;
1.230 + }
1.231 + charStorage=charStorage|character;
1.232 + // Shifts the mask to the correct bit location
1.233 + // Masks (AND's) the valid bits from charStorage
1.234 + // Shifts the valid bits into the low order 8bits
1.235 + // Converts to BASE64 char, Casts the result to an unsigned char (which it should be ?....I hope)
1.236 + encodedChar=(TUint8)Base64ToAscii[((charStorage>>maskShift)&ESixBitMask)];
1.237 +
1.238 + *destStringPtr++=encodedChar;
1.239 + destStringCharNum++;
1.240 +
1.241 + // Add a CRLF every aLineLength number of characters
1.242 + if (destStringCharNum == aLineLength)
1.243 + {
1.244 + destStringCharNum = 0;
1.245 + *destStringPtr++ = '\r';
1.246 + *destStringPtr++ = '\n';
1.247 + }
1.248 + }
1.249 +
1.250 + // Check for not enough chars and pad if required
1.251 + if (maskShift==EFour)
1.252 + {
1.253 + *destStringPtr++=KImcvConvEquals;
1.254 + *destStringPtr++=KImcvConvEquals;
1.255 + }
1.256 + else
1.257 + if(maskShift==ESix)
1.258 + *destStringPtr++=KImcvConvEquals;
1.259 +
1.260 + aDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
1.261 + return ((TInt)(srcStringPtr-srcStringEnd));
1.262 + }