Changeset 151 in libcf for trunk/src/cf_codec.c


Ignore:
Timestamp:
10/31/13 10:17:24 (11 years ago)
Author:
cheese
Message:

#1 fix interface and add util module

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/cf_codec.c

    r129 r151  
    1313#include <stdio.h>
    1414
     15#define BASE64_PADDING_CHAR_INDEX   64
     16
    1517#define ASSERT_ARGS(x)  \
    1618    if ((x))            \
    1719        return CF_ERROR_CODEC_INVALID_ARGS
    1820
    19 const static cf_byte g_ascii_HexDecode[] = {
    20     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  00 -  15 */
    21     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  16 -  31 */
    22     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  32 -  47 */
    23      '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',0x00,0x00,0x00,0x00,0x00,0x00,    /*  48 -  63 */
    24     0x00, 'A', 'A', 'A', 'A', 'A', 'A',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  64 -  79 */
    25     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  80 -  95 */
    26     0x00, 'a', 'a', 'a', 'a', 'a', 'a',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  96 - 111 */
    27     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 112 - 127 */
    28     /* end of ascii character */
    29     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 128 - 143 */
    30     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 144 - 159 */
    31     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 160 - 175 */
    32     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 176 - 191 */
    33     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 192 - 207 */
    34     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 208 - 223 */
    35     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 224 - 239 */
    36     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 240 - 255 */
    37 };
    38 
    39 const static char g_table_Base64Encode[] = {
    40 #define BASE64_PADDING_CHAR_INDEX   64
    41     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',     /* 00 - 07 */
    42     'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',     /* 08 - 15 */
    43     'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',     /* 16 - 23 */
    44     'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',     /* 24 - 31 */
    45     'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',     /* 32 - 39 */
    46     'o', 'p', 'q', 'r', 's', 't', 'u', 'v',     /* 40 - 47 */
    47     'w', 'x', 'y', 'z', '0', '1', '2', '3',     /* 48 - 55 */
    48     '4', '5', '6', '7', '8', '9', '+', '/',     /* 56 - 63 */
    49     '='                                         /* padding */
    50 };
    51 
    52 const static cf_byte g_ascii_Base64Decode[] = {
    53     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /*  00 -  15 */
    54     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /*  16 -  31 */
    55     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  62,0xff,0xff,0xff,  63,    /*  32 -  47 */
    56       52,  53,  54,  55,  56,  57,  58,  59,  60,  61,0xff,0xff,0xff,  64,0xff,0xff,    /*  48 -  63 */
    57     0xff,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,    /*  64 -  79 */
    58       15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,0xff,0xff,0xff,0xff,0xff,    /*  80 -  95 */
    59     0xff,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,    /*  96 - 111 */
    60       41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,0xff,0xff,0xff,0xff,0xff,    /* 112 - 127 */
    61     /* end of ascii character */
    62     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /* 128 - 143 */
    63     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /* 144 - 159 */
    64     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /* 160 - 175 */
    65     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /* 176 - 191 */
    66     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /* 192 - 207 */
    67     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /* 208 - 223 */
    68     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /* 224 - 239 */
    69     0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /* 240 - 255 */
    70 };
    71 
    72 
    7321/**
    7422 * hex-encode
     
    8836                     char           * hex)
    8937{
    90     size_t  iter = 0;
    91     size_t  hexlen = len * 2 + 1;
    92 
    93     const cf_byte   * ptr = bin;
    94 
    95     const static char   hexchar[] = {'0', '1', '2', '3',
    96                                      '4', '5', '6', '7',
    97                                      '8', '9', 'a', 'b',
    98                                      'c', 'd', 'e', 'f'};
     38    const cf_byte   * src = bin;
     39    char            * dst = hex;
     40
     41    const static char   hexenc[] = {
     42        '0', '1', '2', '3', '4', '5', '6', '7',
     43        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
     44    };
    9945
    10046    ASSERT_ARGS (bin == NULL);
    10147    ASSERT_ARGS (hex == NULL);
    10248
    103     for (iter = 0 ; iter < hexlen ; iter += 2, ptr++)
    104     {
    105         hex[iter    ] = hexchar[((*(ptr)) >> 4) & 0x0f];
    106         hex[iter + 1] = hexchar[((*(ptr))     ) & 0x0f];
    107     }
    108     hex[hexlen - 1] = '\0';
     49    for ( ; *src ; src++)
     50    {
     51        *dst++ = hexenc[((*src) >> 4) & 0x0f];
     52        *dst++ = hexenc[((*src)     ) & 0x0f];
     53    }
     54    *dst = '\0';
    10955
    11056    return CF_OK;
     
    11460 * hex-decode
    11561 *
    116  * \return 성공 시, 디코딩된 바이너리 데이터의 길이; 실패 시, 오류 코드
     62 * \return 성공 시, CF_OK; 실패 시, 오류 코드
    11763 *
    11864 * \param hex   16진수 문자열
     
    12975{
    13076    size_t      length = 0; /* absolutely even-number */
    131     size_t      iter = 0;
    132     size_t      binlen = 0;
    133 
    134     const char  * ptr = hex;
     77
     78    const char  * src = hex;
     79    cf_byte     * dst = bin;
    13580    char        buf = 0;
    13681    cf_byte     val = 0;
    13782    cf_byte     asciiHex = 0;
    13883
     84    const static cf_byte hexdec[] = {
     85        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  00 -  07 */
     86        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  08 -  15 */
     87        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  16 -  23 */
     88        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  24 -  31 */
     89        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  32 -  39 */
     90        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  40 -  47 */
     91         '0', '0', '0', '0', '0', '0', '0', '0',    /*  48 -  55 */
     92         '0', '0',0x00,0x00,0x00,0x00,0x00,0x00,    /*  56 -  63 */
     93        0x00, 'A', 'A', 'A', 'A', 'A', 'A',0x00,    /*  64 -  71 */
     94        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  71 -  79 */
     95        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  80 -  87 */
     96        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /*  88 -  95 */
     97        0x00, 'a', 'a', 'a', 'a', 'a', 'a',0x00,    /*  96 - 103 */
     98        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 104 - 111 */
     99        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    /* 112 - 119 */
     100        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00     /* 120 - 127 */
     101    };
     102
    139103    ASSERT_ARGS (hex == NULL);
    140104    ASSERT_ARGS (bin == NULL);
    141105    ASSERT_ARGS (len == NULL);
    142106
    143     *len = 0;
    144 
    145     for ( ; g_ascii_HexDecode[(int)*ptr] && *ptr ; ptr++, length++);
    146 
    147     if (*ptr)
     107    for ( ; hexdec[(int)*src] && *src ; src++, length++);
     108
     109    if (*src)
    148110        return CF_ERROR_CODEC_NOT_HEXSTRING;
    149111
    150     binlen = length / 2;
    151 
    152     for (iter = 0, ptr = hex ; *ptr ; iter++)
     112    for (src = hex ; *src ; )
    153113    {
    154114        val = 0;    /* init/re-init docoding-buffer */
    155115
    156116        /* decode one character */
    157 #define DECODE_HEX(x)                               \
    158         do {                                        \
    159         buf = *(x);                                 \
    160         val = (cf_byte)(val << 4);          \
    161         asciiHex = g_ascii_HexDecode[(int)buf];     \
    162                                                     \
    163         val |=  (cf_byte)                       \
     117#define DECODE_HEX(x)                   \
     118        do {                            \
     119        buf = *(x);                     \
     120        val = (cf_byte)(val << 4);      \
     121        asciiHex = hexdec[(int)buf];    \
     122        \
     123        val |=  (cf_byte)               \
    164124                (buf - asciiHex + (asciiHex == '0' ? 0 : 10));  \
    165125        } while (0)
    166126
    167127        /* decode one byte by decode two character */
    168         DECODE_HEX (ptr++);
    169         DECODE_HEX (ptr++);
    170 
    171         bin[iter] = val;
    172     }
    173 
    174     * len = binlen;
     128        DECODE_HEX (src++);
     129        DECODE_HEX (src++);
     130
     131        *dst++ = val;
     132    }
     133    *len = length / 2;
    175134
    176135    return CF_OK;
     
    196155    const cf_byte   * src = bin;
    197156    char            * dst = base64;
     157
     158    const static char base64enc[] = {
     159        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', /* 00 - 07 */
     160        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', /* 08 - 15 */
     161        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', /* 16 - 23 */
     162        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', /* 24 - 31 */
     163        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 32 - 39 */
     164        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', /* 40 - 47 */
     165        'w', 'x', 'y', 'z', '0', '1', '2', '3', /* 48 - 55 */
     166        '4', '5', '6', '7', '8', '9', '+', '/', /* 56 - 63 */
     167        '='                                     /* padding */
     168    };
    198169
    199170    ASSERT_ARGS (src == NULL);
     
    207178#define SEXTUPLE_E_6(__x)   (((__x[2])     ) & 0x3f)
    208179
    209     for ( ; src - bin < len - 2 ; src += 3)
    210     {
    211         *dst++ = g_table_Base64Encode[SEXTUPLE_E_1 (src)];
    212         *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (src)|
    213                                       SEXTUPLE_E_3 (src)];
    214         *dst++ = g_table_Base64Encode[SEXTUPLE_E_4 (src)|
    215                                       SEXTUPLE_E_5 (src)];
    216         *dst++ = g_table_Base64Encode[SEXTUPLE_E_6 (src)];
    217     }
    218 
    219     if (src - bin < len)
    220     {
    221         *dst++ = g_table_Base64Encode[SEXTUPLE_E_1 (src)];
     180    for ( ; (size_t)(src - bin) < len - 2 ; src += 3)
     181    {
     182        *dst++ = base64enc[SEXTUPLE_E_1 (src)];
     183        *dst++ = base64enc[SEXTUPLE_E_2 (src) | SEXTUPLE_E_3 (src)];
     184        *dst++ = base64enc[SEXTUPLE_E_4 (src) | SEXTUPLE_E_5 (src)];
     185        *dst++ = base64enc[SEXTUPLE_E_6 (src)];
     186    }
     187
     188    if ((size_t)(src - bin) < len)
     189    {
     190        *dst++ = base64enc[SEXTUPLE_E_1 (src)];
    222191
    223192        if (src - bin == len - 1)
    224193        {
    225             *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (src)];
    226             *dst++ = g_table_Base64Encode[BASE64_PADDING_CHAR_INDEX];
     194            *dst++ = base64enc[SEXTUPLE_E_2 (src)];
     195            *dst++ = base64enc[BASE64_PADDING_CHAR_INDEX];
    227196        }
    228197        else
    229198        {
    230             *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (src)|
    231                                           SEXTUPLE_E_3 (src)];
    232             *dst++ = g_table_Base64Encode[SEXTUPLE_E_4 (src)];
     199            *dst++ = base64enc[SEXTUPLE_E_2 (src) | SEXTUPLE_E_3 (src)];
     200            *dst++ = base64enc[SEXTUPLE_E_4 (src)];
    233201        }
    234202
    235         *dst++ = g_table_Base64Encode[BASE64_PADDING_CHAR_INDEX];
     203        *dst++ = base64enc[BASE64_PADDING_CHAR_INDEX];
    236204    }
    237205    *dst = '\0';
     
    243211 * Base64-decode
    244212 *
    245  * \return 성공 시, 디코딩된 바이너리 데이터의 길이; 실패 시, 오류 코드
     213 * \return 성공 시, CF_OK; 실패 시, 오류 코드
    246214 *
    247215 * \param base64    base64 문자열
     
    259227    const char  * src = base64;
    260228    cf_byte     * dst = bin;
    261     int         remain = 0;
    262     int         binlen = 0;
     229    size_t      remain = 0;
     230    size_t      binlen = 0;
     231
     232    const static cf_byte base64dec[] = {
     233        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /*  00 -  07 */
     234        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /*  08 -  15 */
     235        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /*  16 -  23 */
     236        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /*  24 -  31 */
     237        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,    /*  32 -  39 */
     238        0xff,0xff,0xff,  62,0xff,0xff,0xff,  63,    /*  40 -  47 */
     239          52,  53,  54,  55,  56,  57,  58,  59,    /*  48 -  55 */
     240          60,  61,0xff,0xff,0xff,  64,0xff,0xff,    /*  56 -  63 */
     241        0xff,   0,   1,   2,   3,   4,   5,   6,    /*  64 -  71 */
     242           7,   8,   9,  10,  11,  12,  13,  14,    /*  71 -  79 */
     243          15,  16,  17,  18,  19,  20,  21,  22,    /*  80 -  87 */
     244          23,  24,  25,0xff,0xff,0xff,0xff,0xff,    /*  88 -  95 */
     245        0xff,  26,  27,  28,  29,  30,  31,  32,    /*  96 - 103 */
     246          33,  34,  35,  36,  37,  38,  39,  40,    /* 104 - 111 */
     247          41,  42,  43,  44,  45,  46,  47,  48,    /* 112 - 119 */
     248          49,  50,  51,0xff,0xff,0xff,0xff,0xff     /* 120 - 127 */
     249    };
    263250
    264251    ASSERT_ARGS (src == NULL);
     
    266253    ASSERT_ARGS (len == NULL);
    267254
    268     *len = 0;
    269 
    270     while (g_ascii_Base64Decode[(int)*src] < BASE64_PADDING_CHAR_INDEX) src++;
     255    while (base64dec[(int)*src] < BASE64_PADDING_CHAR_INDEX) src++;
    271256
    272257    if (*src == 0xff)
    273258        return CF_ERROR_CODEC_NOT_BASE64;
    274259
    275     remain = (int)(src - base64);
     260    remain = (size_t)(src - base64);
    276261    binlen = ((remain + 2/* max padding length */) / 4) * 3;
    277262
    278 #define SEXTUPLE_D_1(src)   (g_ascii_Base64Decode[(int)src[0]] << 2)
    279 #define SEXTUPLE_D_2(src)   (g_ascii_Base64Decode[(int)src[1]] >> 4)
    280 #define SEXTUPLE_D_3(src)   (g_ascii_Base64Decode[(int)src[1]] << 4)
    281 #define SEXTUPLE_D_4(src)   (g_ascii_Base64Decode[(int)src[2]] >> 2)
    282 #define SEXTUPLE_D_5(src)   (g_ascii_Base64Decode[(int)src[2]] << 6)
    283 #define SEXTUPLE_D_6(src)   (g_ascii_Base64Decode[(int)src[3]]     )
     263#define SEXTUPLE_D_1(src)   (base64dec[(int)src[0]] << 2)
     264#define SEXTUPLE_D_2(src)   (base64dec[(int)src[1]] >> 4)
     265#define SEXTUPLE_D_3(src)   (base64dec[(int)src[1]] << 4)
     266#define SEXTUPLE_D_4(src)   (base64dec[(int)src[2]] >> 2)
     267#define SEXTUPLE_D_5(src)   (base64dec[(int)src[2]] << 6)
     268#define SEXTUPLE_D_6(src)   (base64dec[(int)src[3]]     )
    284269
    285270    for (src = base64 ; remain > 4 ; remain -= 4, src += 4)
     
    297282        *dst++ = (cf_byte)(SEXTUPLE_D_5 (src) | SEXTUPLE_D_6 (src));
    298283
    299     return binlen - (4 - remain);
    300 }
     284    *len = binlen - (4 - remain);
     285
     286    return CF_OK;
     287}
Note: See TracChangeset for help on using the changeset viewer.