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


Ignore:
Timestamp:
05/18/13 18:57:13 (11 years ago)
Author:
cheese
Message:

#1 fix bug on codec and arrange file flag

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/cf_codec.c

    r89 r90  
    3434
    3535const static char g_table_Base64Encode[] = {
    36 #define PADDING_CHAR_INDEX  64
     36#define BASE64_PADDING_CHAR_INDEX   64
    3737    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',     /* 00 - 07 */
    3838    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',     /* 08 - 15 */
     
    110110 * hex-decode
    111111 *
    112  * @return 성공 시, CF_OK; 실패 시, 오류 코드
     112 * @return 성공 시, 디코딩된 바이너리 데이터의 길이; 실패 시, 오류 코드
    113113 *
    114114 * @param hex   16진수 문자열
    115115 * @param bin   바이너리 데이터를 저장할 주소
    116  * @param len   바이너리 데이터의 길이를 저장할 주소
    117116 *
    118117 * @remark
     
    121120int
    122121CF_Codec_Hex_Decode (const char     * hex,
    123                      unsigned char  * bin,
    124                      size_t         * len)
    125 {
    126     int     result = 0;
    127 
     122                     unsigned char  * bin)
     123{
    128124    size_t  length = strlen (hex);  /* absolutely even-number */
    129125    size_t  iter = 0;
    130     size_t  binlen = length / 2;
     126    int     binlen = (int)length / 2;
    131127
    132128    const char      * ptr = hex;
     
    137133    ASSERT_ARGS (hex == NULL);
    138134    ASSERT_ARGS (bin == NULL);
    139     ASSERT_ARGS (len == NULL);
    140135
    141136    for (iter = 0 ; iter < binlen ; iter++)
     
    164159    }
    165160
    166     *len = binlen;
    167 
    168     return result;
     161    return binlen;
    169162}
    170163
     
    179172 *
    180173 * @remark
    181  * base64는 할당된 메모리이며, 크기는 '\0'를 포함하여 (((len + 2) / 3) * 4) + 1
    182  *
    183  * @see http://sourceforge.net/p/predef/wiki/Endianness/
     174 * base64는 할당된 메모리이며, 크기는 ((len + 2) / 3) * 4
     175 * (null-character 제외)
    184176 */
    185177int
     
    188180                        char                * base64)
    189181{
    190     size_t  iter = 0;
    191     char    * ptr = base64;
    192 
    193     ASSERT_ARGS (bin    == NULL);
    194     ASSERT_ARGS (base64 == NULL);
    195 
    196 #define SEXTUPLE_E_1(__x,_idx)  ((__x[_idx    ] >> 2) & 0x3f)
    197 #define SEXTUPLE_E_2(__x,_idx)  ((__x[_idx    ] << 4) & 0x30)
    198 #define SEXTUPLE_E_3(__x,_idx)  ((__x[_idx + 1] >> 4) & 0x0f)
    199 #define SEXTUPLE_E_4(__x,_idx)  ((__x[_idx + 1] << 2) & 0x3c)
    200 #define SEXTUPLE_E_5(__x,_idx)  ((__x[_idx + 2] >> 6) & 0x03)
    201 #define SEXTUPLE_E_6(__x,_idx)  ((__x[_idx + 2]     ) & 0x3f)
    202 
    203     for (iter = 0 ; iter < len - 2 ; iter += 3)
    204     {
    205         *ptr++ = g_table_Base64Encode[SEXTUPLE_E_1 (bin, iter)];
    206         *ptr++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin, iter)|
    207                                       SEXTUPLE_E_3 (bin, iter)];
    208         *ptr++ = g_table_Base64Encode[SEXTUPLE_E_4 (bin, iter)|
    209                                       SEXTUPLE_E_5 (bin, iter)];
    210         *ptr++ = g_table_Base64Encode[SEXTUPLE_E_6 (bin, iter)];
    211     }
    212 
    213     if (iter < len)
    214     {
    215         *ptr++ = g_table_Base64Encode[SEXTUPLE_E_1 (bin, iter)];
    216 
    217         if (iter == (len - 1))
     182    const unsigned char * src = bin;
     183    char                * dst = base64;
     184
     185    ASSERT_ARGS (src == NULL);
     186    ASSERT_ARGS (dst == NULL);
     187
     188#define SEXTUPLE_E_1(__x)   (((__x[0]) >> 2) & 0x3f)
     189#define SEXTUPLE_E_2(__x)   (((__x[0]) << 4) & 0x30)
     190#define SEXTUPLE_E_3(__x)   (((__x[1]) >> 4) & 0x0f)
     191#define SEXTUPLE_E_4(__x)   (((__x[1]) << 2) & 0x3c)
     192#define SEXTUPLE_E_5(__x)   (((__x[2]) >> 6) & 0x03)
     193#define SEXTUPLE_E_6(__x)   (((__x[2])     ) & 0x3f)
     194
     195    for ( ; src - bin < len - 2 ; src += 3)
     196    {
     197        *dst++ = g_table_Base64Encode[SEXTUPLE_E_1 (src)];
     198        *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (src)|
     199                                      SEXTUPLE_E_3 (src)];
     200        *dst++ = g_table_Base64Encode[SEXTUPLE_E_4 (src)|
     201                                      SEXTUPLE_E_5 (src)];
     202        *dst++ = g_table_Base64Encode[SEXTUPLE_E_6 (src)];
     203    }
     204
     205    if (src - bin < len)
     206    {
     207        *dst++ = g_table_Base64Encode[SEXTUPLE_E_1 (src)];
     208
     209        if (src - bin == len - 1)
    218210        {
    219             *ptr++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin, iter)];
    220             *ptr++ = g_table_Base64Encode[PADDING_CHAR_INDEX];
     211            *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin)];
     212            *dst++ = g_table_Base64Encode[BASE64_PADDING_CHAR_INDEX];
    221213        }
    222214        else
    223215        {
    224             *ptr++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin, iter)|
    225                                           SEXTUPLE_E_3 (bin, iter)];
    226             *ptr++ = g_table_Base64Encode[SEXTUPLE_E_4 (bin, iter)];
     216            *dst++ = g_table_Base64Encode[SEXTUPLE_E_2 (bin)|
     217                                          SEXTUPLE_E_3 (bin)];
     218            *dst++ = g_table_Base64Encode[SEXTUPLE_E_4 (bin)];
    227219        }
    228220
    229         *ptr++ = g_table_Base64Encode[PADDING_CHAR_INDEX];
    230     }
    231     *ptr = '\0';
     221        *dst++ = g_table_Base64Encode[BASE64_PADDING_CHAR_INDEX];
     222    }
     223    *dst = '\0';
    232224
    233225    return CF_OK;
     
    237229 * Base64-decode
    238230 *
    239  * @return 성공 시, CF_OK; 실패 시, 오류 코드
     231 * @return 성공 시, 디코딩된 바이너리 데이터의 길이; 실패 시, 오류 코드
    240232 *
    241233 * @param base64    base64 문자열
    242234 * @param bin       바이너리 데이터를 저장할 주소
    243  * @param len       바이너리 데이터의 길이를 저장할 주소
    244  *
    245  * @remark
    246  * base64는 할당된 메모리이며, 크기는 (strlen (base64) - <'=' 개수>) / 4 * 3
    247  *
    248  * @see http://sourceforge.net/p/predef/wiki/Endianness/
     235 *
     236 * @remark
     237 * base64는 할당된 메모리이며, 크기는 (strlen (base64) - <패딩 길이>) / 4 * 3
    249238 */
    250239int
    251240CF_Codec_Base64_Decode (const char      * base64,
    252                         unsigned char   * bin,
    253                         size_t          * len)
    254 {
    255     size_t          remain = 0;
     241                        unsigned char   * bin)
     242{
     243    int             remain = 0;
    256244    const char      * src = base64;
    257245    unsigned char   * dst = bin;
    258     size_t          binlen = 0;
    259 
    260     ASSERT_ARGS (base64 == NULL);
    261     ASSERT_ARGS (bin    == NULL);
    262     ASSERT_ARGS (len    == NULL);
    263 
    264     while (*src && g_ascii_Base64Decode[(int)*src] < PADDING_CHAR_INDEX) src++;
     246    int             binlen = 0;
     247
     248    ASSERT_ARGS (src == NULL);
     249    ASSERT_ARGS (dst == NULL);
     250
     251    while (g_ascii_Base64Decode[(int)*src] < BASE64_PADDING_CHAR_INDEX) src++;
    265252
    266253    if (*src)
    267254        return CF_ERROR_CODEC_NOT_BASE64;
    268255
    269     remain = (size_t)(src - base64);
     256    remain = (int)(src - base64);
    270257    binlen = ((remain + 3) / 4) * 3;
    271258
     
    286273    if (remain > 1)
    287274        *dst++ = (unsigned char)(SEXTUPLE_D_1 (src) | SEXTUPLE_D_2 (src));
    288 
    289275    if (remain > 2)
    290276        *dst++ = (unsigned char)(SEXTUPLE_D_3 (src) | SEXTUPLE_D_4 (src));
    291 
    292277    if (remain > 3)
    293278        *dst++ = (unsigned char)(SEXTUPLE_D_5 (src) | SEXTUPLE_D_6 (src));
    294279
    295     *dst++ = '\0';
    296     *len = binlen;
    297 
    298     return CF_OK;
    299 }
     280    return binlen;
     281}
Note: See TracChangeset for help on using the changeset viewer.