321 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			321 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /***********************************************************************
 | |
|  * 
 | |
|  *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
 | |
|  *
 | |
|  *  This library is free software; you can redistribute it and/or
 | |
|  *  modify it under the terms of the GNU Lesser General Public
 | |
|  *  License as published by the Free Software Foundation; version 2.1
 | |
|  *  of the License.
 | |
|  *
 | |
|  *  This library is distributed in the hope that it will be useful,
 | |
|  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  *  Library Lesser General Public License for more details.
 | |
|  *
 | |
|  *  You should have received a copy of the GNU Lesser General Public
 | |
|  *  License along with this library; if not, Novell, Inc.
 | |
|  * 
 | |
|  *  To contact Novell about this file by physical or electronic mail, 
 | |
|  *  you may find current contact information at www.novell.com.
 | |
|  * 
 | |
|  *  Author: Juan Carlos Luciani <jluciani@novell.com>
 | |
|  *
 | |
|  ***********************************************************************/
 | |
| 
 | |
| //===[ Include files ]=====================================================
 | |
| 
 | |
| #include "internal.h"
 | |
| 
 | |
| //===[ Type definitions ]==================================================
 | |
| 
 | |
| //===[ Function prototypes ]===============================================
 | |
| 
 | |
| //===[ Global variables ]==================================================
 | |
| 
 | |
| // Tables for Base64 encoding and decoding
 | |
| static const int8_t  g_Base64[] =
 | |
|     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | |
| 
 | |
| static const uint8_t g_Expand64[256] =
 | |
| {
 | |
|     /* ASCII table */
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
 | |
|     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
 | |
|     64,  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, 64, 64, 64, 64, 64,
 | |
|     64, 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, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
 | |
|     64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
 | |
| };
 | |
| 
 | |
| 
 | |
| //++=======================================================================
 | |
| CasaStatus
 | |
| EncodeData(
 | |
|    IN    const void *pData,
 | |
|    IN    const int32_t dataLen,
 | |
|    INOUT char **ppEncodedData,
 | |
|    INOUT int32_t *pEncodedDataLen)
 | |
| //
 | |
| //  Arguments: 
 | |
| //
 | |
| //  Returns:   
 | |
| //
 | |
| //  Description:  
 | |
| //
 | |
| // L2
 | |
| //=======================================================================--
 | |
| {
 | |
|    CasaStatus  retStatus;
 | |
|    int         encodedSize;
 | |
|    char        *pTmp;
 | |
| 
 | |
|    DbgTrace(3, "-EncodeData- Start\n", 0);
 | |
| 
 | |
|    // Determine the encoded size and allocate a buffer to hold the encoded data
 | |
|    encodedSize = ((dataLen * 4 + 2) / 3) - (dataLen % 3 ) + 4;
 | |
|    pTmp = (char*) malloc(encodedSize);
 | |
|    *ppEncodedData = pTmp;
 | |
|    if (*ppEncodedData)
 | |
|    {
 | |
|       uint8_t  *pOut, *pIn;
 | |
|       int      i;
 | |
| 
 | |
|       // Setup pointers to move through the buffers
 | |
|       pIn = (uint8_t*) pData;
 | |
|       pOut = (uint8_t*) *ppEncodedData;
 | |
| 
 | |
|       // Perform the encoding
 | |
|       for (i = 0; i < dataLen - 2; i += 3)
 | |
|       {
 | |
|           *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F];
 | |
|           *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) |
 | |
|                           ((int32_t)(pIn[i + 1] & 0xF0) >> 4)];
 | |
|           *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2) |
 | |
|                           ((int32_t)(pIn[i + 2] & 0xC0) >> 6)];
 | |
|           *pOut++ = g_Base64[pIn[i + 2] & 0x3F];
 | |
|       }
 | |
|       if (i < dataLen)
 | |
|       {
 | |
|           *pOut++ = g_Base64[(pIn[i] >> 2) & 0x3F];
 | |
|           if (i == (dataLen - 1))
 | |
|           {
 | |
|               *pOut++ = g_Base64[((pIn[i] & 0x3) << 4)];
 | |
|               *pOut++ = '=';
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|               *pOut++ = g_Base64[((pIn[i] & 0x3) << 4) |
 | |
|                               ((int32_t)(pIn[i + 1] & 0xF0) >> 4)];
 | |
|               *pOut++ = g_Base64[((pIn[i + 1] & 0xF) << 2)];
 | |
|           }
 | |
|           *pOut++ = '=';
 | |
|       }
 | |
|       *pOut++ = '\0';
 | |
| 
 | |
|       // Return the encoded data length
 | |
|       *pEncodedDataLen = (int32_t)(pOut - (uint8_t*)*ppEncodedData); 
 | |
| 
 | |
|       // Success
 | |
|       retStatus = CASA_STATUS_SUCCESS;
 | |
|    }
 | |
|    else
 | |
|    {
 | |
|       DbgTrace(0, "-EncodeData- Buffer allocation failure\n", 0);
 | |
| 
 | |
|       retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                   CASA_FACILITY_AUTHTOKEN,
 | |
|                                   CASA_STATUS_INSUFFICIENT_RESOURCES);
 | |
|    }
 | |
| 
 | |
|    DbgTrace(3, "-EncodeData- End, retStatus = %0X\n", retStatus);
 | |
| 
 | |
|    return retStatus;
 | |
| }
 | |
| 
 | |
| 
 | |
| //++=======================================================================
 | |
| CasaStatus
 | |
| DecodeData(
 | |
|    IN    const char *pEncodedData,
 | |
|    IN    const int32_t encodedDataLen, // Does not include NULL terminator
 | |
|    INOUT void **ppData,
 | |
|    INOUT int32_t *pDataLen)
 | |
| //
 | |
| //  Arguments: 
 | |
| //
 | |
| //  Returns:   
 | |
| //
 | |
| //  Description:  
 | |
| //
 | |
| // L2
 | |
| //=======================================================================--
 | |
| {
 | |
|    CasaStatus  retStatus;
 | |
|    int         i, j;
 | |
|    int         decodedSize;
 | |
| 
 | |
|    DbgTrace(3, "-DecodeData- Start\n", 0);
 | |
| 
 | |
|    // Determine the decoded size
 | |
|    for (i = 0, j = 0; i < encodedDataLen; i++)
 | |
|        if (g_Expand64[((uint8_t*) pEncodedData)[i]] < 64)
 | |
|            j++;
 | |
|    decodedSize = (j * 3 + 3) / 4;
 | |
| 
 | |
|    // Allocate buffer to hold the decoded data
 | |
|    *ppData = malloc(decodedSize);
 | |
|    if (*ppData)
 | |
|    {
 | |
|       bool  endReached = false;
 | |
|       uint8_t  c0, c1, c2, c3;
 | |
|       uint8_t  *p, *q;
 | |
| 
 | |
|       // Initialize parameters that will be used during the decode operation
 | |
|       c0 = c1 = c2 = c3 = 0;
 | |
|       p = (uint8_t*) pEncodedData;
 | |
|       q = (uint8_t*) *ppData;
 | |
| 
 | |
|       // Decode the data
 | |
|       //
 | |
|       // Loop through the data, piecing back information. Any newlines, and/or
 | |
|       // carriage returns need to be skipped.
 | |
|       while (j > 4)
 | |
|       {
 | |
|           while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
 | |
|               p++;
 | |
|           if (64 == g_Expand64[*p])
 | |
|           {
 | |
|               endReached = true;
 | |
|               break;
 | |
|           }
 | |
|           c0 = *(p++);
 | |
| 
 | |
|           while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
 | |
|               p++;
 | |
|           if (64 == g_Expand64[*p])
 | |
|           {
 | |
|               *(q++) = (uint8_t)(g_Expand64[c0] << 2);
 | |
|               j--;
 | |
|               endReached = true;
 | |
|               break;
 | |
|           }
 | |
|           c1 = *(p++);
 | |
| 
 | |
|           while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
 | |
|               p++;
 | |
|           if (64 == g_Expand64[*p])
 | |
|           {
 | |
|               *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
 | |
|               *(q++) = (uint8_t)(g_Expand64[c1] << 4);
 | |
|               j -= 2;
 | |
|               endReached = true;
 | |
|               break;
 | |
|           }
 | |
|           c2 = *(p++);
 | |
| 
 | |
|           while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
 | |
|               p++;
 | |
|           if (64 == g_Expand64[*p])
 | |
|           {
 | |
|               *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
 | |
|               *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
 | |
|               *(q++) = (uint8_t)(g_Expand64[c2] << 6);
 | |
|               j -= 3;
 | |
|               endReached = true;
 | |
|               break;
 | |
|           }
 | |
|           c3 = *(p++);
 | |
| 
 | |
|           *(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
 | |
|           *(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
 | |
|           *(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]);
 | |
|           j -= 4;
 | |
|       }
 | |
|       if (!endReached)
 | |
|       {
 | |
|           if (j > 1)
 | |
|               *(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4);
 | |
|           if (j > 2)
 | |
|               *(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2);
 | |
|           if (j > 3)
 | |
|               *(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]);
 | |
|       }
 | |
| 
 | |
|       // Return the length of the decoded data
 | |
|       *pDataLen = (int32_t)(q - (uint8_t*)*ppData);
 | |
| 
 | |
|       // Success
 | |
|       retStatus = CASA_STATUS_SUCCESS;
 | |
|    }
 | |
|    else
 | |
|    {
 | |
|       DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0);
 | |
| 
 | |
|       retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
 | |
|                                   CASA_FACILITY_AUTHTOKEN,
 | |
|                                   CASA_STATUS_INSUFFICIENT_RESOURCES);
 | |
|    }
 | |
| 
 | |
|    DbgTrace(3, "-DecodeData- End, retStatus = %0X\n", retStatus);
 | |
| 
 | |
|    return retStatus;
 | |
| }
 | |
| 
 | |
| 
 | |
| //++=======================================================================
 | |
| int
 | |
| dtoul(
 | |
|    IN    char *cp,
 | |
|    IN    int len)
 | |
| //
 | |
| //  Arguments: 
 | |
| //
 | |
| //  Returns:   
 | |
| //
 | |
| //  Abstract:  
 | |
| //
 | |
| //  Notes:
 | |
| //
 | |
| // L0
 | |
| //=======================================================================--
 | |
| {
 | |
|    int   n = 0;
 | |
|    int   i;
 | |
| 
 | |
|    DbgTrace(2, "-dtoul- Start\n", 0);
 | |
| 
 | |
|    for (i = 0; i < len; i++, cp++)
 | |
|    {
 | |
|       // Verify that we are dealing with a valid digit
 | |
|       if (*cp >= '0' && *cp <= '9')
 | |
|       {
 | |
|          n = 10 * n + (*cp - '0');
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|          DbgTrace(0, "-dtoul- Found invalid digit\n", 0);
 | |
|          break;
 | |
|       }
 | |
|    }
 | |
|       
 | |
|    DbgTrace(2, "-dtoul- End, result = %0X\n", n);
 | |
| 
 | |
|    return n;
 | |
| }
 | |
| 
 | |
| 
 | |
| //++=======================================================================
 | |
| //++=======================================================================
 | |
| //++=======================================================================
 | |
| 
 |