omadrm/drmengine/dm/src/b64.cpp
changeset 0 95b198f216e5
child 12 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2004 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:  This class implements the base64 en/decoding.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include "base64.h"
       
    21 
       
    22 /*  6    LOCAL DEFINITIONS */
       
    23 
       
    24 /*  6.1    Local include files */
       
    25 
       
    26 /*  6.2    Local constants */
       
    27 
       
    28 LOCAL_C const TUint8 pBase64[] = 
       
    29 	{                   
       
    30 	0x3e, 0x7f, 0x7f, 0x7f, 0x3f, 0x34, 0x35, 0x36,
       
    31 	0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x7f,
       
    32 	0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x01,
       
    33 	0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
       
    34 	0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
       
    35 	0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
       
    36 	0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x1a, 0x1b,
       
    37 	0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
       
    38 	0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
       
    39 	0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
       
    40 	};
       
    41 
       
    42 /*  6.3    Local macros */
       
    43 #define b64blocks(l) (((l) + 2) / 3 * 4)
       
    44 /* #define b64octets(l)  ((l) / 4  * 3) */
       
    45 
       
    46 /*  6.4    Local data types */
       
    47 
       
    48 /*  6.5    Local data structures */
       
    49 
       
    50 /*  6.6    Local function prototypes */
       
    51 
       
    52 LOCAL_C TInt b64valid(TUint8 *);
       
    53 
       
    54 /*  7    MODULE CODE */
       
    55 
       
    56 /* ========================================================================= */
       
    57 
       
    58 /*  7.2 */
       
    59 
       
    60 /* Functional description
       
    61  *
       
    62  * This function does base64 decoding. As the outputted buffer is always 33% shorter than 
       
    63  * the input buffer, the caller may want to reallocate the buffer after calling this function.
       
    64  *
       
    65  * Parameters
       
    66  *
       
    67  * Pointer to source containing data to decode
       
    68  *
       
    69  source
       
    70  *
       
    71  * Length of source buffer
       
    72  *
       
    73  length
       
    74  *
       
    75  * pointer to the destination buffer
       
    76  * Note: the user must allocate memory for this buffer that its length at least can not be shorter than
       
    77  *       the length of source. The user also can use same buffer for both source and destination.
       
    78  *
       
    79  destination
       
    80  *
       
    81  * length of the buffer allocated
       
    82  *
       
    83  destination_length
       
    84  *
       
    85  * Return values
       
    86  *
       
    87  *	byte 0 if OK else > 0
       
    88  */
       
    89 
       
    90 /* ---------------------------------------------------------------------- */
       
    91 
       
    92 TInt b64decode(TUint8 *source, TUint32 length, TUint8 *destination, TUint32 *destination_length)
       
    93 	{
       
    94 	/* Data structures */
       
    95 
       
    96 	/*  Code  */
       
    97     
       
    98 	TUint8   *buf/*, *pbuf*/;     /* Decoding buffer pointers. */
       
    99 	register TUint32 x = 0;          /* General purpose integers. */
       
   100 	TUint32 buf_index = 0;  /* current index in destination buffer */
       
   101 
       
   102 	
       
   103 	/* buffer to avoid allocating wholly new buffer for output */
       
   104 	TUint8 localBuffer[4] = {0,0,0,0}; 
       
   105 	TUint8* pLocalBufferOutPointer = 0;
       
   106 	
       
   107 	register TUint32 i = 0;
       
   108 	TUint32 num;
       
   109 
       
   110     TUint8   c = 0;          /* Character to decode. */
       
   111     TUint8 localBufferIndex = 0;
       
   112 
       
   113     /*	int32 buf_length = 0; */ /* new length of destination buf */
       
   114 	const TUint8 pad = 0x3d; /* '=' */
       
   115 
       
   116 	if(!source || length == 0 || !destination || !destination_length)
       
   117 		{
       
   118 		return KErrArgument;
       
   119 		}
       
   120 
       
   121 	/* Collating sequence independant "===". */
       
   122 
       
   123 	/* Calculate the amount of '=' in the end of the source */
       
   124 	for(x=0, buf=source + (length-1); *buf == pad; buf --)
       
   125 		{
       
   126 		x++;
       
   127 		}
       
   128 
       
   129 	/* max allow 3 "===" in the end of content */
       
   130 	if (x > 3)
       
   131 		{                                       
       
   132 		return KErrArgument;
       
   133 		}
       
   134 
       
   135 	/* Save the encoded string pointer. */
       
   136 	// pbuf = destination; 
       
   137 
       
   138 	/* save address for first output block */
       
   139 	pLocalBufferOutPointer = destination;
       
   140 	x = 0; /* Initialize index. */
       
   141 
       
   142 	localBufferIndex = 0;
       
   143 
       
   144 
       
   145 	Mem::Copy(localBuffer, source, 4);
       
   146 
       
   147 	for (i = length; i != 0; i-- ) /* Decode every byte of the base 64 string */
       
   148 		{
       
   149 		/* c = *pbuf++; */
       
   150 		c = localBuffer[localBufferIndex++];
       
   151 
       
   152 		if(localBufferIndex == 4)
       
   153 			{
       
   154 			localBufferIndex = 0;
       
   155 			
       
   156 			source = source + 4;
       
   157 
       
   158 			/* INPUT: copy next input block to local buffer */
       
   159 			num = i > 4 ? 4 : i - 1;
       
   160 			if(num > 0)
       
   161 				{
       
   162 				Mem::Copy(localBuffer, source, num);
       
   163 				}
       
   164 			}
       
   165 
       
   166 		/* Ignore "=". */
       
   167 		if  (c == pad)
       
   168 			{
       
   169 			break; /* this must be the end of the buffer, or else ve have a invalid character */
       
   170 			}
       
   171 		
       
   172 		if  (c == '\n' || c == '\r' || c == '\t') /* ignore linefeed tab and cr */
       
   173 			{
       
   174 			continue;
       
   175 			}
       
   176 		
       
   177 		/* Valid Base64 Index? */
       
   178 		if (!b64valid(&c))
       
   179 			{
       
   180 			/* b64free(buf); */
       
   181 			return KErrArgument;
       
   182 			}
       
   183         
       
   184 		/* Decode 4 byte words into 3 byte octets.*/
       
   185 		switch(x % 4)
       
   186 			{
       
   187 			case 0: /* Byte 0 of word.*/
       
   188 				pLocalBufferOutPointer[buf_index] = (TInt8)(c << 2);
       
   189 				break;                          
       
   190 			case 1: /* Byte 1 of word. */
       
   191 				pLocalBufferOutPointer[buf_index] |= c >> 4;
       
   192 				buf_index ++;
       
   193 				pLocalBufferOutPointer[buf_index] = (TInt8)( (c & 0x0f) << 4 );
       
   194 				break;
       
   195 			case 2: /* Byte 2 of word. */
       
   196 				pLocalBufferOutPointer[buf_index] |= c >> 2;
       
   197 				buf_index ++;
       
   198 				pLocalBufferOutPointer[buf_index] = (TInt8)( (c & 0x03) << 6 );
       
   199 				break;
       
   200 			case 3: /* Byte 3 of word. */
       
   201 				pLocalBufferOutPointer[buf_index] |= c;
       
   202 				buf_index ++;
       
   203 				break;
       
   204 			default: /* useless, just to depress warnings */
       
   205 				break;
       
   206 			}
       
   207 		
       
   208 		x++; /* Increment word byte. */
       
   209 		
       
   210 
       
   211 		} /* while */
       
   212 
       
   213 
       
   214 	/* make sure that there is zero at the end of the buffer
       
   215 	   though buf[buf_index] shoule be zero after decoding
       
   216 	*/
       
   217 
       
   218 	
       
   219 	/* pbuf[buf_index+1] = 0; */
       
   220 
       
   221 	/*buf[buf_index+1]=0*/
       
   222 	/* don't return the size of the buffer (buf_length), but the data size we put in (buf_index)*/
       
   223 	*destination_length = buf_index; 
       
   224 	return KErrNone;
       
   225 	}
       
   226 
       
   227 /*  7.3 */
       
   228 
       
   229 /* Functional description
       
   230  *
       
   231  * This function validates the character according to the base64 rules,
       
   232  * and changes it to the corresponding value in the table.
       
   233  *
       
   234  * Parameters
       
   235  *
       
   236  * Pointer to character to validate
       
   237  *
       
   238  c
       
   239  *
       
   240  * Return values
       
   241  *
       
   242  *	TRUE if character is valid else FALSE.
       
   243  */
       
   244 
       
   245 /* ---------------------------------------------------------------------- */
       
   246 
       
   247 LOCAL_C TInt b64valid(TUint8 *c)
       
   248 	{
       
   249 	/* Data structures */
       
   250 
       
   251 	/*  Code  */
       
   252 
       
   253 	/* If not within the range of the table, return false. */
       
   254 	if ((*c < 0x2b) || (*c > 0x7a))
       
   255 		{
       
   256 		return 0;
       
   257 		}
       
   258 	/* If it falls within one of the gaps, return false. */
       
   259 	if ((*c = pBase64[*c - 0x2b]) == 0x7f)
       
   260 		{
       
   261 		return 0;
       
   262 		}
       
   263 	
       
   264 	return 1; /* Otherwise, return true. */
       
   265 	}
       
   266 
       
   267 /*  7.4 */
       
   268 
       
   269 /* Functional description
       
   270  *
       
   271  * This function allocates a buffer in the size of the parameter.
       
   272  *
       
   273  * Parameters
       
   274  *
       
   275  * Size of buffer to allocate
       
   276  *
       
   277  length
       
   278  *
       
   279  * Return values
       
   280  *
       
   281  *	pointer to buffer
       
   282  */
       
   283 
       
   284 /* ---------------------------------------------------------------------- */
       
   285 #ifdef BUILD_BASE64_ENCODE
       
   286 
       
   287 LOCAL TUint8 *b64buffer(TUint32 length)
       
   288 	{
       
   289 	/* Data structures */
       
   290 
       
   291 	/*  Code  */
       
   292 
       
   293 	TUint8 *buf; /* buffer pointers. */
       
   294 	
       
   295 	if  (!length) /* dont allow buf size  0 */
       
   296 		{
       
   297 		return  NULL;
       
   298 		}
       
   299 	
       
   300 	buf = (TUint8 *) DRM_BLOCK_ALLOC(length); 
       
   301 	
       
   302 	return buf; /* Return the pointer or null. */
       
   303 	}
       
   304 #endif /* #ifdef BUILD_BASE64_ENCODE */
       
   305 
       
   306 /* End of File */
       
   307