vpnengine/utlbase64/src/base64.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Base64 encoder/decoder
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <eikenv.h>
       
    21 #include "base64.h"
       
    22 
       
    23 ////////////////////////////////////////////////////////////////////////////////////////
       
    24 //	Constructor
       
    25 ////////////////////////////////////////////////////////////////////////////////////////
       
    26 EXPORT_C TBase64Codec::TBase64Codec()
       
    27 {
       
    28 	// Initialize base64
       
    29 	InitBase64();
       
    30 }
       
    31 
       
    32 ////////////////////////////////////////////////////////////////////////////////////////
       
    33 //	Initialize decoding array
       
    34 ////////////////////////////////////////////////////////////////////////////////////////
       
    35 void TBase64Codec::InitBase64(void)
       
    36 {
       
    37 	TUint8 i;
       
    38 	Mem::Fill(iD64, sizeof(iD64), B64_IGN);
       
    39 	for (i=0;i<sizeof(Kb64);i++)
       
    40 	{
       
    41 		iD64[Kb64[i]]=i;
       
    42 	}
       
    43 	iD64[B64_NOP_CHR]=B64_NOP_VAL;
       
    44 }
       
    45 
       
    46 ////////////////////////////////////////////////////////////////////////////////////////
       
    47 //	Base64 encoding function using buffers allocated by the caller
       
    48 ////////////////////////////////////////////////////////////////////////////////////////
       
    49 EXPORT_C TInt TBase64Codec::Base64Encode(const TDesC8 &aRawData, const TDes8 &aEncodedData)
       
    50 {
       
    51 	TInt i;
       
    52 	TInt j;
       
    53 	TInt datalen;
       
    54 	TUint8 block[3];
       
    55 	const TUint8 *fromPtr;
       
    56 	TUint8 *toPtr;
       
    57 	TUint count = 0;
       
    58 	TInt lengthIncludingLinebreaks;
       
    59 	TInt lengthWithoutLinebreaks;
       
    60 
       
    61 
       
    62 	i=0;
       
    63 	fromPtr = aRawData.Ptr();
       
    64 	toPtr = CONST_CAST(TUint8*, aEncodedData.Ptr());
       
    65 	datalen = aRawData.Size();
       
    66 	lengthWithoutLinebreaks = ((datalen + 3)/ 3) * 4;
       
    67 	lengthIncludingLinebreaks = lengthWithoutLinebreaks + (lengthWithoutLinebreaks) / MAXLINELEN - ((lengthWithoutLinebreaks % MAXLINELEN)?0:1); 
       
    68 	if(aEncodedData.MaxLength() < lengthIncludingLinebreaks)
       
    69 		return KErrArgument;
       
    70 
       
    71 	for (j=0;j<datalen;j+=3)
       
    72 	{
       
    73 		/* 11111100>>2 */
       
    74 		/* 00000011<<4 + 11110000>>4 */
       
    75 		/*               00001111<<2 + 11000000>>6 */
       
    76 		/*                             00111111    */
       
    77 		Mem::FillZ(block, 3);
       
    78 		Mem::Copy(block, &fromPtr[j], datalen-j<3?datalen-j:3);
       
    79 		toPtr[i++] = Kb64[(block[0]&0xfc)>>2]; 
       
    80 		toPtr[i++] = Kb64[((block[0]&0x03)<<4)+(block[1]>>4)];
       
    81 		if (datalen-j>1)
       
    82 		{
       
    83 			toPtr[i++] = Kb64[((block[1]&0x0f)<<2)+(block[2]>>6)]; 
       
    84 		}
       
    85 		else
       
    86 		{
       
    87 			toPtr[i++] = B64_NOP_CHR;
       
    88 		}
       
    89 		if (datalen-j>2)
       
    90 		{
       
    91 			toPtr[i++]=Kb64[block[2]&0x3f]; 
       
    92 		}
       
    93 		else
       
    94 		{
       
    95 			toPtr[i++] = B64_NOP_CHR;
       
    96 		}
       
    97 		count += 4;
       
    98 		// Add linebreaks every 76th characters
       
    99 		// Don't add it after the last full length line
       
   100 		if(count >= MAXLINELEN && j < datalen - 3)
       
   101 		{
       
   102 			toPtr[i++] = B64_LINEBREAK;
       
   103 			count = 0;
       
   104 		}
       
   105 	}
       
   106 	
       
   107 	CONST_CAST(TDes8 &, aEncodedData).SetLength(i);
       
   108 	return KErrNone;
       
   109 }
       
   110 
       
   111 ////////////////////////////////////////////////////////////////////////////////////////
       
   112 //	Base64 decoding function using buffers allocated by the caller
       
   113 ////////////////////////////////////////////////////////////////////////////////////////
       
   114 EXPORT_C TInt TBase64Codec::Base64Decode(const TDesC8 &aEncodedData, const TDes8 &aDecodedData)
       
   115 {
       
   116 	TInt i;
       
   117 	TInt j;
       
   118 	TInt k;
       
   119 	TInt blocklen;
       
   120 	TInt datalen;
       
   121 	const TUint8 *fromPtr;
       
   122 	TUint8 *toPtr;
       
   123 	
       
   124 	TUint8 c = 0;
       
   125 	TUint8 block[4];
       
   126 
       
   127 	InitBase64();
       
   128 	
       
   129 	i=0;
       
   130 	j=0;
       
   131 	fromPtr = aEncodedData.Ptr();
       
   132 	toPtr = CONST_CAST(TUint8*, aDecodedData.Ptr());
       
   133 	datalen = aEncodedData.Size();
       
   134 	if(aDecodedData.MaxLength() < (datalen / 4) * 3)
       
   135 		return KErrArgument;
       
   136 	
       
   137 	while ((datalen > 0) && (j <= datalen))
       
   138 	{
       
   139 		blocklen=0;
       
   140 		Mem::Fill(block,'\0',sizeof(block));
       
   141 		for (k=0;k<4;k++) /* skip non base64 characters */
       
   142 		{
       
   143 			while (j++ <= datalen && (c=iD64[*fromPtr++])==B64_IGN) {;}
       
   144 			if (j<=datalen)
       
   145 			{
       
   146 				block[k]=c;
       
   147 				if (c!=B64_NOP_VAL)
       
   148 				{
       
   149 					blocklen++;
       
   150 				}
       
   151 				else
       
   152 				{
       
   153 					block[k]=0;
       
   154 				}
       
   155 			}
       
   156 			else
       
   157 			{
       
   158 				block[k]=0;
       
   159 			}
       
   160 		}
       
   161 		if (blocklen)
       
   162 		{
       
   163 			toPtr[i+0] = STATIC_CAST(TUint8, (block[0]<<2) + (block[1]>>4));
       
   164 
       
   165 			if(blocklen > 1)
       
   166 				toPtr[i+1] = STATIC_CAST(TUint8, ((block[1]&0x0f)<<4) + (block[2]>>2));
       
   167 
       
   168 			if(blocklen > 2)
       
   169 				toPtr[i+2] = STATIC_CAST(TUint8, ((block[2]&0x03)<<6) + (block[3]));
       
   170 
       
   171 			i+=blocklen-1;
       
   172 		}
       
   173 	}
       
   174 	CONST_CAST(TDes8 &, aDecodedData).SetLength(i);
       
   175 	return KErrNone;
       
   176 }
       
   177 
       
   178 ////////////////////////////////////////////////////////////////////////////////////////
       
   179 //	Base64 encoding function, buffer allocated by the function and returned to the caller
       
   180 ////////////////////////////////////////////////////////////////////////////////////////
       
   181 EXPORT_C HBufC8* TBase64Codec::Base64EncodeLC(const TDesC8 &aRawData)
       
   182 {
       
   183 	HBufC8 *outBuf = NULL;
       
   184 	TInt rCode;
       
   185 	TUint lengthIncludingLinebreaks;
       
   186 	TUint lengthWithoutLinebreaks;
       
   187 
       
   188 	lengthWithoutLinebreaks =((aRawData.Length() + 3)/ 3) * 4;
       
   189 	lengthIncludingLinebreaks = lengthWithoutLinebreaks + (lengthWithoutLinebreaks) / MAXLINELEN - ((lengthWithoutLinebreaks % MAXLINELEN)?0:1); 
       
   190 	outBuf = HBufC8::NewLC(lengthIncludingLinebreaks);
       
   191 	TPtr8 outDes = outBuf->Des();
       
   192 	rCode = Base64Encode(aRawData, outDes);
       
   193 	if(rCode != KErrNone)
       
   194 	{
       
   195 		CleanupStack::Pop();
       
   196 		delete outBuf;
       
   197 		outBuf = NULL;
       
   198 	}
       
   199 	return (outBuf);
       
   200 }
       
   201 
       
   202 ////////////////////////////////////////////////////////////////////////////////////////
       
   203 //	Base64 decoding function, buffer allocated by the function and returned to the caller
       
   204 ////////////////////////////////////////////////////////////////////////////////////////
       
   205 EXPORT_C HBufC8* TBase64Codec::Base64DecodeLC(const TDesC8 &aEncodedData)
       
   206 {
       
   207 	HBufC8 *outBuf = NULL;
       
   208 	TInt rCode;
       
   209 	
       
   210 	outBuf = HBufC8::NewLC(((aEncodedData.Length() / 4) * 3));
       
   211 	TPtr8 outDes = outBuf->Des();
       
   212 	rCode = Base64Decode(aEncodedData, outDes);
       
   213 	if(rCode != KErrNone)
       
   214 	{
       
   215 		CleanupStack::Pop();
       
   216 		delete outBuf;
       
   217 		outBuf = NULL;
       
   218 	}
       
   219 	return (outBuf);
       
   220 }
       
   221