--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptomgmtlibs/securityutils/source/secutil/base64.cpp Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,210 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* Base64 encoding and decoding functions.
+*
+*/
+
+
+
+
+/**
+ @file
+*/
+
+#include "base64.h"
+
+// Constants used by the Base64 algorithm
+const TUint8 TBase64::iAlphabet[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+const TInt8 KImcvLookUpStartOffset = 43;
+const TUint8 KImcvConvEquals = '=';
+const TInt8 AsciiToBase64[80]=
+ {
+ 62, -1, -1, -1, 63, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, -1, -1, -1, 64, -1,
+ -1, -1, 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, -1, -1,
+ -1, -1, -1, -1, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+ };
+const TInt8 Base64ToAscii[65]=
+ {
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 97, 98, 99,100,
+ 101,102,103,104,105,106,107,108,109,110,
+ 111,112,113,114,115,116,117,118,119,120,
+ 121,122, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 43, 47, 61
+ };
+
+EXPORT_C TBase64::TBase64() :
+ iShiftStored(0),
+ iMaskShiftStored(ESix)
+ {
+ }
+
+EXPORT_C void TBase64::Initialize()
+ {
+ iMaskShiftStored = ESix;
+ }
+
+//Encodes data to Base64.
+EXPORT_C HBufC8* TBase64::EncodeLC(const TDesC8& aSrcString)
+ {
+ // Allocate and clear destination string
+ TInt destLen = ((aSrcString.Length() - 1) / 3 + 1) * 4;
+ HBufC8* destString = HBufC8::NewMaxLC(destLen);
+ TPtr8 destPtr = destString->Des();
+
+ // Initialise variables
+ const TUint8* srcStringPtr = aSrcString.Ptr();
+ const TUint8* srcStringEnd = aSrcString.Length() + srcStringPtr;
+ TUint8* destStringPtr = (TUint8*)destString->Ptr();
+ TUint8* destStringPtrBase = destStringPtr;
+
+ TInt character = 0;
+ TUint8 encodedChar = 0;
+ TInt charStorage = 0;
+ TInt maskShift = EZero;
+
+ while (srcStringPtr <= srcStringEnd)
+ {
+ // maskShift is used as a char read counter
+ if(maskShift == ESix)
+ {
+ // If the 3rd char read is also the last char then the while loop
+ // is broken on the next check.
+ if(srcStringPtr == srcStringEnd)
+ srcStringPtr++;
+ maskShift = EZero;
+ character = 0;
+ }
+ else
+ {
+ if (srcStringPtr == srcStringEnd)
+ character=0;
+ else
+ character = *srcStringPtr;
+
+ srcStringPtr++;
+ // Shifts charStorage ready for the next char
+ charStorage = charStorage << 8;
+ maskShift += ETwo;
+ }
+ charStorage = charStorage | character;
+ // Shifts the mask to the correct bit location
+ // Masks (AND's) the valid bits from charStorage
+ // Shifts the valid bits into the low order 8bits
+ // Converts to BASE64 char, Casts the result to an unsigned
+ // char (which it should be ?....I hope)
+ encodedChar = (TUint8)Base64ToAscii[((charStorage >> maskShift) & ESixBitMask)];
+ *destStringPtr++ = encodedChar;
+ }
+
+ // Check for not enough chars and pad if required
+ if (maskShift == EFour)
+ {
+ *destStringPtr++ = KImcvConvEquals;
+ *destStringPtr++ = KImcvConvEquals;
+ }
+ else
+ if (maskShift == ESix)
+ *destStringPtr++ = KImcvConvEquals;
+
+ destPtr.SetLength((TInt)(destStringPtr - destStringPtrBase));
+ return destString;
+ }
+
+//Decodes Base64-encoded data.
+EXPORT_C HBufC8* TBase64::DecodeLC(const TDesC8& aSrcString, TBool& aNeedMoreData)
+ {
+ // The source string must be a multiple of 4 bytes long
+ if (aSrcString.Length() & 0x3)
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ TInt decodedInt = 0;
+ TInt8 offsetChar = 0;
+ TUint8 decodedChar = 0;
+
+ // Find out how long the decoded string will be.
+ TInt outLen = aSrcString.Length() / 4 * 3;
+ if (aSrcString[aSrcString.Length() - 1] == '=')
+ outLen--;
+ if (aSrcString[aSrcString.Length() - 2] == '=')
+ outLen--;
+
+ // Construct output buffer.
+ HBufC8* destString = HBufC8::NewMaxLC(outLen);
+ TPtr8 destPtr = destString->Des();
+ destPtr.Zero();
+
+ // Initialise variables
+ const TUint8* srcStringPtr = aSrcString.Ptr();
+ const TUint8* srcStringEnd = aSrcString.Length() + srcStringPtr;
+ TUint8* destStringPtr = (TUint8*)destString->Ptr();
+ TUint8* destStringPtrBase = destStringPtr;
+ TInt maskShift = iMaskShiftStored;
+ TInt shiftStorage = iShiftStored;
+
+ // Main character process loop
+ while (srcStringPtr<srcStringEnd)
+ {
+ offsetChar = (TInt8)(*srcStringPtr - KImcvLookUpStartOffset);
+ srcStringPtr++;
+
+ // Check for valid B64 character
+ if ((offsetChar >= 0) && (offsetChar < 80))
+ {
+ // Read in next character and B64 decode
+ decodedInt = AsciiToBase64[offsetChar];
+
+ // Exits when a PAD char is reached
+ if(decodedInt == EPadChar)
+ {
+ destPtr.SetLength((TInt)(destStringPtr - destStringPtrBase));
+ aNeedMoreData = EFalse;
+ return destString;
+ }
+
+ // Ensures the first 2 chars of 4 are received before processing
+ if(maskShift == ESix)
+ maskShift = EFour;
+ else
+ {
+ shiftStorage = shiftStorage << ESix;
+ shiftStorage = shiftStorage | decodedInt;
+ decodedChar = (TUint8)((shiftStorage >> maskShift) & EEightBitMask);
+
+ if((maskShift -= ETwo) < EZero)
+ maskShift = ESix;
+
+ *destStringPtr++ = decodedChar;
+ }
+ shiftStorage = decodedInt;
+ }
+ }
+ iShiftStored = shiftStorage;
+ iMaskShiftStored = maskShift;
+
+ destPtr.SetLength((TInt)(destStringPtr - destStringPtrBase));
+ aNeedMoreData = maskShift < ESix;
+ return destString;
+ }
+