Changeset 90 in libcf


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

#1 fix bug on codec and arrange file flag

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/cf_codec.h

    r88 r90  
    2525CF_EXPORT int
    2626CF_Codec_Hex_Decode         (const char     * hex,
    27                              unsigned char  * bin,
    28                              size_t         * len);
     27                             unsigned char  * bin);
    2928
    3029CF_EXPORT int
     
    3534CF_EXPORT int
    3635CF_Codec_Base64_Decode      (const char     * base64,
    37                              unsigned char  * bin,
    38                              size_t         * len);
     36                             unsigned char  * bin);
    3937
    4038#ifdef __cplusplus
  • trunk/include/cf_file.h

    r86 r90  
    1111
    1212#include "cf_base.h"
    13 #include <fcntl.h>
     13
     14#include <stddef.h>
    1415
    1516/** 파일 열기 옵션 플래그 */
    1617typedef enum {
    17     CF_FILE_READ    = O_RDONLY, /**< 읽기 전용 */
    18     CF_FILE_WRITE   = O_WRONLY, /**< 쓰기 전용 */
    19     CF_FILE_RW      = O_RDWR,   /**< 읽기/쓰기 */
    20     CF_FILE_CREATE  = O_CREAT,  /**< 파일이 존재하지 않으면 생성 */
    21     CF_FILE_TRUNC   = O_TRUNC,  /**< 파일이 존재하면 비우기 */
    22     CF_FILE_APPEND  = O_APPEND  /**< 파일이 존재하면 이어서 쓰기 */
     18    CF_FILE_READ        = 0x0001,   /**< 읽기 전용 */
     19    CF_FILE_WRITE       = 0x0002,   /**< 쓰기 전용 */
     20    CF_FILE_RW          = 0x0004,   /**< 읽기/쓰기 */
     21    CF_FILE_CREATE      = 0x0008,   /**< 파일이 존재하지 않으면 생성 */
     22    CF_FILE_TRUNC       = 0x0010,   /**< 파일이 존재하면 비우기 */
     23    CF_FILE_APPEND      = 0x0020    /**< 파일이 존재하면 이어서 쓰기 */
    2324} E_CF_FILE_FLAG, CF_FILE_FLAG;
    2425
  • 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}
  • trunk/src/cf_file.c

    r86 r90  
    88
    99#include <stdio.h>
     10#include <fcntl.h>
    1011#include <errno.h>
    1112#include <sys/stat.h>
     
    5152        return CF_ERROR_FILE_INVALID_ARGS
    5253
     54static int
     55CF_File_Local_ConvertFlag (const CF_FILE_FLAG flag)
     56{
     57    int result = 0;
     58
     59    if (flag & CF_FILE_READ)    result |= O_RDONLY;
     60    if (flag & CF_FILE_WRITE)   result |= O_WRONLY;
     61    if (flag & CF_FILE_RW)      result |= O_RDWR;
     62    if (flag & CF_FILE_CREATE)  result |= O_CREAT;
     63    if (flag & CF_FILE_TRUNC)   result |= O_TRUNC;
     64    if (flag & CF_FILE_APPEND)  result |= O_APPEND;
     65
     66    return result;
     67}
     68
    5369/**
    5470 * 파일 열기
     
    6985    ASSERT_ARGS (path == NULL);
    7086
    71     result = open (path, (int)(flag|O_BINARY));
    72 
     87    result = open (path, CF_File_Local_ConvertFlag (flag) | O_BINARY);
    7388    if (result < 0)
    7489        return CF_ERROR_FILE_OPEN;
     
    88103{
    89104    int result = 0;
     105    int flag = 0;
    90106   
    91107    ASSERT_ARGS (path == NULL);
    92108
    93     result = open (path, CF_FILE_CREATE|CF_FILE_WRITE|CF_FILE_TRUNC, FILE_MODE);
    94 
     109    flag = CF_File_Local_ConvertFlag (CF_FILE_CREATE|
     110                                      CF_FILE_WRITE |
     111                                      CF_FILE_TRUNC);
     112
     113    result = open (path, flag, FILE_MODE);
    95114    if (result < 0)
    96115        return CF_ERROR_FILE_CREATE;
     
    114133
    115134    result = close (fd);
    116 
    117135    if (result < 0)
    118136        return CF_ERROR_FILE_CLOSE;
     
    141159
    142160    result = (int) read (fd, buf, len);
    143 
    144161    if (result < 0)
    145162        return CF_ERROR_FILE_READ;
     
    168185
    169186    result = (int) write (fd, buf, len);
    170 
    171187    if (result != len)
    172188      return CF_ERROR_FILE_WRITE;
     
    190206
    191207    result = (int) lseek (fd, 0, SEEK_END);
    192 
    193208    if (result < 0 || lseek (fd, 0, SEEK_SET) < 0)
    194209        return CF_ERROR_FILE_GET_SIZE;
  • trunk/test/codec.c

    r88 r90  
    1414    char encode[512] = {0x00,};
    1515    unsigned char bin[512] = {0x00,};
    16     size_t length = 0;
     16    int length = 0;
    1717
    1818    /* hex */
     
    2525
    2626    CF_DEBUG_PRINT (stderr, "= Convert hex to binary =\n");
    27     CF_Codec_Hex_Decode (encode, bin, &length);
    28     CF_DEBUG_PRINT_BIN (stderr, bin, length, "bin    : %s\n", bin);
     27    length = CF_Codec_Hex_Decode (encode, bin);
     28    if (length < 0) {
     29        // error
     30    }
     31    CF_DEBUG_PRINT_BIN (stderr, bin, (size_t)length, "bin    : %s\n", bin);
    2932
    3033    memset (bin   , 0x00, sizeof (bin));
     
    4043
    4144    CF_DEBUG_PRINT (stderr, "= Convert base64 to binary =\n");
    42     CF_Codec_Base64_Decode (encode, bin, &length);
    43     CF_DEBUG_PRINT_BIN (stderr, bin, length, "bin    : %s\n", bin);
     45    length = CF_Codec_Base64_Decode (encode, bin);
     46    if (length < 0) {
     47        // error
     48    }
     49    CF_DEBUG_PRINT_BIN (stderr, bin, (size_t)length, "bin    : %s\n", bin);
    4450
    4551    return 0;
  • trunk/test/test.c

    r88 r90  
    389389    char encode[512] = {0x00,};
    390390    unsigned char bin[512] = {0x00,};
    391     size_t length = 0;
     391    int length = 0;
    392392
    393393    /* hex */
     
    400400
    401401    CF_DEBUG_PRINT (stderr, "= Convert hex to binary =\n");
    402     CF_Codec_Hex_Decode (encode, bin, &length);
    403     CF_DEBUG_PRINT_BIN (stderr, bin, length, "bin    : %s\n", bin);
     402    length = CF_Codec_Hex_Decode (encode, bin);
     403    if (length < 0) {
     404        // error
     405    }
     406    CF_DEBUG_PRINT_BIN (stderr, bin, (size_t)length, "bin    : %s\n", bin);
    404407
    405408    memset (bin   , 0x00, sizeof (bin));
     
    415418
    416419    CF_DEBUG_PRINT (stderr, "= Convert base64 to binary =\n");
    417     CF_Codec_Base64_Decode (encode, bin, &length);
    418     CF_DEBUG_PRINT_BIN (stderr, bin, length, "bin    : %s\n", bin);
    419 }
     420    length = CF_Codec_Base64_Decode (encode, bin);
     421    if (length < 0) {
     422        // error
     423    }
     424    CF_DEBUG_PRINT_BIN (stderr, bin, (size_t)length, "bin    : %s\n", bin);
     425}
Note: See TracChangeset for help on using the changeset viewer.