os/ossrv/genericservices/httputils/Authentication/TConvBase64.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2006-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
// TBase64.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <tconvbase64.h>
sl@0
    19
sl@0
    20
/**
sl@0
    21
TBase64 constructor
sl@0
    22
*/
sl@0
    23
EXPORT_C TBase64::TBase64(): iShiftStored(0), iMaskShiftStored(ESix)
sl@0
    24
	{}
sl@0
    25
	
sl@0
    26
	
sl@0
    27
/**
sl@0
    28
	Encodes an ASCII string to Base64 string.
sl@0
    29
sl@0
    30
	@param aSrcString The source string in ASCII code.
sl@0
    31
	@param rDestString The destination string with converted base64 values.
sl@0
    32
	@return Number of characters in the source string that were not Encoded.
sl@0
    33
*/	
sl@0
    34
EXPORT_C TInt TBase64::Encode(const TDesC8& aSrcString, TDes8& rDestString)
sl@0
    35
	{
sl@0
    36
    // Clears the destination string
sl@0
    37
    rDestString.Zero();
sl@0
    38
    // Initialise variables
sl@0
    39
    const TUint8* srcStringPtr=aSrcString.Ptr();
sl@0
    40
    const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr;
sl@0
    41
    TUint8* destStringPtr=(TUint8*)rDestString.Ptr();
sl@0
    42
    TUint8* destStringPtrBase=destStringPtr;
sl@0
    43
    TInt character=0;
sl@0
    44
    TUint8 encodedChar=0;
sl@0
    45
    TInt charStorage=0;
sl@0
    46
    TInt maskShift=EZero;
sl@0
    47
    TInt destStringCharNum = 0;
sl@0
    48
sl@0
    49
    while(srcStringPtr<=srcStringEnd)
sl@0
    50
	    {
sl@0
    51
        // maskShift is used as a char read counter
sl@0
    52
	    if(maskShift==ESix)
sl@0
    53
            {
sl@0
    54
	        // If the 3rd char read is also the last char then the while loop
sl@0
    55
            // is broken on the next check.
sl@0
    56
            if(srcStringPtr==srcStringEnd)
sl@0
    57
            	srcStringPtr++;
sl@0
    58
            maskShift=EZero;
sl@0
    59
            character=0;   
sl@0
    60
            }
sl@0
    61
        else
sl@0
    62
            {
sl@0
    63
            if(srcStringPtr==srcStringEnd)
sl@0
    64
	            character=0;
sl@0
    65
            else
sl@0
    66
		        character=*srcStringPtr;
sl@0
    67
 
sl@0
    68
			srcStringPtr++;
sl@0
    69
		    // Shifts charStorage ready for the next char
sl@0
    70
	        charStorage=charStorage<<8;
sl@0
    71
            maskShift+=ETwo;
sl@0
    72
            }
sl@0
    73
        charStorage=charStorage|character;
sl@0
    74
        // Shifts the mask to the correct bit location
sl@0
    75
        // Masks (AND's) the valid bits from charStorage
sl@0
    76
        // Shifts the valid bits into the low order 8bits
sl@0
    77
        // Converts to BASE64 char, Casts the result to an unsigned char (which it should be ?....I hope)
sl@0
    78
        encodedChar=(TUint8)Base64ToAscii[((charStorage>>maskShift)&ESixBitMask)];
sl@0
    79
sl@0
    80
        *destStringPtr++=encodedChar;
sl@0
    81
        destStringCharNum++;
sl@0
    82
sl@0
    83
        // Add a CRLF every KMaxB64EncodedCharsPerLine characters so as not to exceed the line length
sl@0
    84
        // limitation specified in RFC 2822.
sl@0
    85
        if (destStringCharNum == KMaxB64EncodedCharsPerLine)
sl@0
    86
	        {
sl@0
    87
            destStringCharNum = 0;
sl@0
    88
            *destStringPtr++ = '\r';
sl@0
    89
            *destStringPtr++ = '\n';
sl@0
    90
            }
sl@0
    91
		}
sl@0
    92
     
sl@0
    93
    // Check for not enough chars and pad if required
sl@0
    94
    if (maskShift==EFour)
sl@0
    95
	    {
sl@0
    96
        *destStringPtr++=KImcvConvEquals;
sl@0
    97
        *destStringPtr++=KImcvConvEquals;
sl@0
    98
        }
sl@0
    99
    else
sl@0
   100
        if(maskShift==ESix)
sl@0
   101
	        *destStringPtr++=KImcvConvEquals;   
sl@0
   102
            
sl@0
   103
    rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
sl@0
   104
    return ((TInt)(srcStringPtr-srcStringEnd));
sl@0
   105
	}
sl@0
   106
sl@0
   107
/**
sl@0
   108
	Decodes the Base64 string to ASCII pattern.
sl@0
   109
sl@0
   110
	@param aSrcString The source string in Base64 codeset.
sl@0
   111
	@param rDestString The destination string with converted ASCII code values.
sl@0
   112
	@return ETrue if aSrcString is not long enough to decode fully, resulting in the storage of
sl@0
   113
		the last character and requiring another aSrcString (poss 0 length) to be passed to it to clear this character. 
sl@0
   114
		Returns EFalse if the line was decoded OK or the end of the encoded file is reached ie "="
sl@0
   115
*/	
sl@0
   116
EXPORT_C TBool TBase64::Decode(const TDesC8& aSrcString, TDes8& rDestString)
sl@0
   117
	{
sl@0
   118
	TInt decodedInt=0;
sl@0
   119
	TInt8 offsetChar=0;
sl@0
   120
	TUint8 decodedChar=0;
sl@0
   121
	 
sl@0
   122
	// Clears the destination string
sl@0
   123
	rDestString.Zero();
sl@0
   124
sl@0
   125
	// Initialise variables
sl@0
   126
	const TUint8* srcStringPtr=aSrcString.Ptr();
sl@0
   127
	const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr;
sl@0
   128
	TUint8* destStringPtr=(TUint8*)rDestString.Ptr();
sl@0
   129
	TUint8* destStringPtrBase=destStringPtr;
sl@0
   130
sl@0
   131
	TInt maskShift=iMaskShiftStored;
sl@0
   132
	TInt shiftStorage=iShiftStored;
sl@0
   133
	
sl@0
   134
	// Main character process loop
sl@0
   135
	while(srcStringPtr<srcStringEnd)	
sl@0
   136
		{
sl@0
   137
		offsetChar=(TInt8)(*srcStringPtr-KImcvLookUpStartOffset);
sl@0
   138
		srcStringPtr++;
sl@0
   139
sl@0
   140
		// Check for valid B64 character		
sl@0
   141
		if((offsetChar>=0)&&(offsetChar<80))
sl@0
   142
			{
sl@0
   143
			// Read in next character and B64 decode
sl@0
   144
			decodedInt=AsciiToBase64[offsetChar];
sl@0
   145
sl@0
   146
			// Exits when a PAD char is reached
sl@0
   147
			if(decodedInt==EPadChar)
sl@0
   148
				{
sl@0
   149
				rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
sl@0
   150
				return EFalse;
sl@0
   151
				}
sl@0
   152
sl@0
   153
			// Ensures the first 2 chars of 4 are received before processing
sl@0
   154
			if(maskShift==ESix)
sl@0
   155
				maskShift=EFour;
sl@0
   156
			else
sl@0
   157
				{
sl@0
   158
				shiftStorage=shiftStorage<<ESix;
sl@0
   159
				shiftStorage=shiftStorage|decodedInt;
sl@0
   160
				decodedChar=(TUint8)((shiftStorage>>maskShift)&EEightBitMask);
sl@0
   161
				
sl@0
   162
				if((maskShift-=ETwo)<EZero)
sl@0
   163
					maskShift=ESix; 
sl@0
   164
				
sl@0
   165
				*destStringPtr++=decodedChar;
sl@0
   166
				}
sl@0
   167
			shiftStorage=decodedInt;
sl@0
   168
			}
sl@0
   169
		}
sl@0
   170
	iShiftStored=shiftStorage;
sl@0
   171
	iMaskShiftStored=maskShift;
sl@0
   172
	
sl@0
   173
	rDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
sl@0
   174
	
sl@0
   175
	return maskShift<ESix;
sl@0
   176
	}
sl@0
   177
sl@0
   178
sl@0
   179
/**
sl@0
   180
    Encodes an ASCII string to Base64 string.
sl@0
   181
sl@0
   182
    @param aSrcString The source string in ASCII.
sl@0
   183
    @param aDestString The destination string with converted base64 values.
sl@0
   184
    @param aLineLength The maximum line length of the encoded base64 values.
sl@0
   185
         A CR/LF sequence will be added after these many characters. 
sl@0
   186
         The default value is -1, which means no CR/LF is added to output. The encoding is compliant with RFC 4648 
sl@0
   187
    @return Number of characters in the source string that were not encoded.
sl@0
   188
*/  
sl@0
   189
EXPORT_C TInt TBase64::PortableEncode(const TDesC8& aSrcString, TDes8& aDestString, TInt aLineLength)
sl@0
   190
    {
sl@0
   191
    // Clears the destination string
sl@0
   192
    aDestString.Zero();
sl@0
   193
    // Initialise variables
sl@0
   194
    const TUint8* srcStringPtr=aSrcString.Ptr();
sl@0
   195
    const TUint8* srcStringEnd=aSrcString.Length()+srcStringPtr;
sl@0
   196
    TUint8* destStringPtr=(TUint8*)aDestString.Ptr();
sl@0
   197
    TUint8* destStringPtrBase=destStringPtr;
sl@0
   198
    TInt character=0;
sl@0
   199
    TUint8 encodedChar=0;
sl@0
   200
    TInt charStorage=0;
sl@0
   201
    TInt maskShift=EZero;
sl@0
   202
    TInt destStringCharNum = 0;
sl@0
   203
sl@0
   204
    while(srcStringPtr<=srcStringEnd)
sl@0
   205
        {
sl@0
   206
        // maskShift is used as a char read counter
sl@0
   207
        if(maskShift==ESix)
sl@0
   208
            {
sl@0
   209
            // If the 3rd char read is also the last char then the while loop
sl@0
   210
            // is broken on the next check.
sl@0
   211
            if(srcStringPtr==srcStringEnd)
sl@0
   212
                srcStringPtr++;
sl@0
   213
            maskShift=EZero;
sl@0
   214
            character=0;   
sl@0
   215
            }
sl@0
   216
        else
sl@0
   217
            {
sl@0
   218
            if(srcStringPtr==srcStringEnd)
sl@0
   219
                character=0;
sl@0
   220
            else
sl@0
   221
                character=*srcStringPtr;
sl@0
   222
 
sl@0
   223
            srcStringPtr++;
sl@0
   224
            // Shifts charStorage ready for the next char
sl@0
   225
            charStorage=charStorage<<8;
sl@0
   226
            maskShift+=ETwo;
sl@0
   227
            }
sl@0
   228
        charStorage=charStorage|character;
sl@0
   229
        // Shifts the mask to the correct bit location
sl@0
   230
        // Masks (AND's) the valid bits from charStorage
sl@0
   231
        // Shifts the valid bits into the low order 8bits
sl@0
   232
        // Converts to BASE64 char, Casts the result to an unsigned char (which it should be ?....I hope)
sl@0
   233
        encodedChar=(TUint8)Base64ToAscii[((charStorage>>maskShift)&ESixBitMask)];
sl@0
   234
sl@0
   235
        *destStringPtr++=encodedChar;
sl@0
   236
        destStringCharNum++;
sl@0
   237
sl@0
   238
        // Add a CRLF every aLineLength number of characters 
sl@0
   239
        if (destStringCharNum == aLineLength)
sl@0
   240
            {
sl@0
   241
            destStringCharNum = 0;
sl@0
   242
            *destStringPtr++ = '\r';
sl@0
   243
            *destStringPtr++ = '\n';
sl@0
   244
            }
sl@0
   245
        }
sl@0
   246
     
sl@0
   247
    // Check for not enough chars and pad if required
sl@0
   248
    if (maskShift==EFour)
sl@0
   249
        {
sl@0
   250
        *destStringPtr++=KImcvConvEquals;
sl@0
   251
        *destStringPtr++=KImcvConvEquals;
sl@0
   252
        }
sl@0
   253
    else
sl@0
   254
        if(maskShift==ESix)
sl@0
   255
            *destStringPtr++=KImcvConvEquals;   
sl@0
   256
            
sl@0
   257
    aDestString.SetLength((TInt)(destStringPtr-destStringPtrBase));
sl@0
   258
    return ((TInt)(srcStringPtr-srcStringEnd));
sl@0
   259
    }