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