Back to index

im-sdk  12.3.91
encode.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <errno.h>
00005 #include <iconv.h>
00006 #include <strings.h>
00007 #include <X11/Xmd.h>
00008 #include "encode.h"
00009 
00010 typedef struct _LangGroup_Info {
00011        int    lang_id;
00012        char   *lang_name;
00013        int    *support_encodes;
00014        char   **support_locales;
00015 } LangGroup_Info;
00016 
00017 /* supported encodes for specified language */
00018 int zh_CN_encodes[] = {
00019        ENCODE_GB2312,
00020        ENCODE_GBK,
00021        ENCODE_GB18030,
00022        ENCODE_ERROR,
00023 };
00024 
00025 int zh_TW_encodes[] = {
00026        ENCODE_BIG5,
00027        ENCODE_EUC_TW,
00028        ENCODE_ERROR,
00029 };
00030 
00031 int zh_HK_encodes[] = {
00032        ENCODE_BIG5HK,
00033        ENCODE_ERROR,
00034 };
00035 
00036 int th_TH_encodes[] = {
00037        ENCODE_EUC_TH,
00038        ENCODE_ERROR,
00039 };
00040 
00041 int ko_KR_encodes[] = {
00042        ENCODE_EUC_KO,
00043        ENCODE_ERROR,
00044 };
00045 
00046 /* supported locales for specified language */
00047 char *zh_CN_locales[] = {
00048        "zh_CN.EUC",
00049        "zh_CN.GBK",
00050        "zh_CN.GB18030",
00051        "zh_CN.UTF-8",
00052        "zh_CN",
00053        "zh.GBK",
00054        "zh.UTF-8",
00055        "zh",
00056        NULL
00057 };
00058 
00059 char *zh_TW_locales[] = {
00060        "zh_TW.EUC",
00061        "zh_TW.BIG5",
00062        "zh_TW.UTF-8",
00063        "zh_TW",
00064        NULL
00065 };
00066 
00067 char *zh_HK_locales[] = {
00068        "zh_HK.BIG5HK",
00069        "zh_HK.UTF-8",
00070        NULL
00071 };
00072 
00073 char *th_TH_locales[] = {
00074        "th_TH.TIS620",
00075        "th_TH.ISO8859-11",
00076        "th_TH.UTF-8",
00077        "th_TH",
00078        "th",
00079        NULL
00080 };
00081 
00082 char *ko_KR_locales[] = {
00083        "ko",
00084        "ko_KR.EUC",
00085        "ko.UTF-8",
00086        "ko_KR.UTF-8",
00087        NULL
00088 };
00089 
00090 LangGroup_Info langgroup_info[LANGS_NUM] = {
00091        {
00092               LANG_ZH_CN,
00093               "zh_CN",
00094               zh_CN_encodes,
00095               zh_CN_locales,
00096        },
00097        {
00098               LANG_ZH_TW,
00099               "zh_TW",
00100               zh_TW_encodes,
00101               zh_TW_locales,
00102        },
00103        {
00104               LANG_ZH_HK,
00105               "zh_HK",
00106               zh_HK_encodes,
00107               zh_HK_locales,
00108        },
00109        {
00110               LANG_TH_TH,
00111               "th_TH",
00112               th_TH_encodes,
00113               th_TH_locales,
00114        },
00115        {
00116               LANG_KO_KR,
00117               "ko_KR",
00118               ko_KR_encodes,
00119               ko_KR_locales,
00120        },
00121 };
00122 
00123 typedef struct _Encode_Info {
00124        int    encode_id;
00125        char   **called_names;
00126        char   **support_locales;
00127        char   *iconv_codeset_name;
00128        iconv_t fd_iconv_to_utf8;
00129        iconv_t fd_iconv_from_utf8;
00130 } Encode_Info;
00131 
00132 /* encode names */
00133 char *GB2312_names[] = {
00134        "GB2312",
00135        "GB",
00136        NULL
00137 };
00138 
00139 char *GBK_names[] = {
00140        "GBK",
00141        NULL
00142 };
00143 
00144 char *GB18030_names[] = {
00145        "GB18030",
00146        NULL
00147 };
00148 
00149 char *BIG5_names[] = {
00150        "BIG5",
00151        NULL
00152 };
00153 
00154 char *EUC_TW_names[] = {
00155        "EUC_TW",
00156        NULL
00157 };
00158 
00159 char *BIG5HK_names[] = {
00160        "BIG5HK",
00161        NULL
00162 };
00163 
00164 char *EUC_TH_names[] = {
00165        "EUC_TH",
00166        NULL
00167 };
00168 
00169 char *EUC_KO_names[] = {
00170        "EUC_KO",
00171        NULL
00172 };
00173 
00174 char *UTF8_names[] = {
00175        "UTF-8",
00176        "UTF_8",
00177        "UTF8",
00178        NULL
00179 };
00180 
00181 /* supported locales for specified encode */
00182 char *GB2312_locales[] = {
00183        "zh_CN.EUC",
00184        "zh_CN",
00185        "zh",
00186        NULL
00187 };
00188 
00189 char *GBK_locales[] = {
00190        "zh_CN.GBK",
00191        "zh.GBK",
00192        "zh_CN.UTF-8",
00193        "zh.UTF-8",
00194        NULL
00195 };
00196 
00197 char *GB18030_locales[] = {
00198        "zh_CN.GB18030",
00199        "zh_CN.UTF-8",
00200        NULL
00201 };
00202 
00203 char *BIG5_locales[] = {
00204        "zh_TW.BIG5",
00205        "zh_TW.UTF-8",
00206        NULL
00207 };
00208 
00209 char *EUC_TW_locales[] = {
00210        "zh_TW.EUC",
00211        "zh_TW",
00212        NULL
00213 };
00214 
00215 char *BIG5HK_locales[] = {
00216        "zh_HK.BIG5HK",
00217        "zh_HK.UTF-8",
00218        NULL
00219 };
00220 
00221 char *EUC_TH_locales[] = {
00222        "th_TH.TIS620",
00223        "th_TH",
00224        "th_TH.UTF-8",
00225        NULL
00226 };
00227 
00228 char *EUC_KO_locales[] = {
00229        "ko",
00230        "ko_KR.EUC",
00231        NULL
00232 };
00233 
00234 char *UTF8_locales[] = {
00235        "ko.UTF-8",
00236        "ko_KR.UTF-8",
00237        "zh_HK.UTF-8",
00238        NULL
00239 };
00240 
00241 /* iconv codeset name for specified encode */
00242 #define GB2312_CODESET_NAME        "zh_CN.euc"
00243 #define GBK_CODESET_NAME    "zh_CN.gbk"
00244 #define GB18030_CODESET_NAME       "zh_CN.gb18030"
00245 #define BIG5_CODESET_NAME   "zh_TW.big5"
00246 #define EUC_TW_CODESET_NAME "zh_TW.euc"
00247 #define BIG5HK_CODESET_NAME "zh_HK.hkscs"
00248 #define EUC_TH_CODESET_NAME "eucTH"
00249 /*
00250 #define EUC_KO_CODESET_NAME "ko_KR.euc"
00251 */
00252 #define EUC_KO_CODESET_NAME "EUC-KR"
00253 #define UTF8_CODESET_NAME   "UTF-8"
00254 
00255 /* unknown encode name */
00256 #define UNKNOWN_ENCODE             "UNKNOWN"
00257 
00258 Encode_Info  encode_info[ENCODES_NUM + 1] = {
00259        { 
00260               ENCODE_GB2312,
00261               GB2312_names,
00262               GB2312_locales,
00263               GB2312_CODESET_NAME,
00264               NULL,
00265               NULL,
00266        },
00267        { 
00268               ENCODE_GBK,
00269               GBK_names,
00270               GBK_locales,
00271               GBK_CODESET_NAME,
00272               NULL,
00273               NULL,
00274        },
00275        { 
00276               ENCODE_GB18030,
00277               GB18030_names,
00278               GB18030_locales,
00279               GB18030_CODESET_NAME,
00280               NULL,
00281               NULL,
00282        },
00283        { 
00284               ENCODE_BIG5,
00285               BIG5_names,
00286               BIG5_locales,
00287               BIG5_CODESET_NAME,
00288               NULL,
00289               NULL,
00290        },
00291        { 
00292               ENCODE_EUC_TW,
00293               EUC_TW_names,
00294               EUC_TW_locales,
00295               EUC_TW_CODESET_NAME,
00296               NULL,
00297               NULL,
00298        },
00299        { 
00300               ENCODE_BIG5HK,
00301               BIG5HK_names,
00302               BIG5HK_locales,
00303               BIG5HK_CODESET_NAME,
00304               NULL,
00305               NULL,
00306        },
00307        { 
00308               ENCODE_EUC_TH,
00309               EUC_TH_names,
00310               EUC_TH_locales,
00311               EUC_TH_CODESET_NAME,
00312               NULL,
00313               NULL,
00314        },
00315        {
00316               ENCODE_EUC_KO,
00317               EUC_KO_names,
00318               EUC_KO_locales,
00319               EUC_KO_CODESET_NAME,
00320               NULL,
00321               NULL,
00322        },
00323        { 
00324               ENCODE_UTF8,
00325               UTF8_names,
00326               UTF8_locales,
00327               UTF8_CODESET_NAME,
00328               NULL,
00329               NULL,
00330        }
00331 };
00332 
00333 iconv_t  fd_iconv_UTF8_to_UTF16 = NULL;
00334 iconv_t  fd_iconv_UTF16_to_UTF8 = NULL;
00335 
00336 char *get_langname_from_langid(int langid)
00337 {
00338        int ret = langid;
00339        
00340        if (langid < 0 || langid >= LANGS_NUM) 
00341               ret = 0;
00342 
00343        return(langgroup_info[ret].lang_name);
00344 }
00345 
00346 char *get_langname_from_locale(char *locale)
00347 {
00348        int lang_id, i, ret;
00349        char *s;
00350 
00351        ret = -1;
00352        for (lang_id = 0; lang_id < LANGS_NUM; lang_id++) {
00353               i = 0;
00354               while (1) {
00355                      s = langgroup_info[lang_id].support_locales[i];
00356                      if (!s || !*s) break;
00357                      if (!strcmp(s, locale)) {
00358                             ret = lang_id;
00359                             break;
00360                      }
00361                      i++;
00362               }
00363               if (ret != -1) break;
00364        }
00365 
00366        if (ret == -1) 
00367               ret = 0;
00368 
00369        return(langgroup_info[ret].lang_name);
00370 }
00371 
00372 char *get_langname_from_encodeid(int encodeid)
00373 {
00374        int lang_id, i, ret;
00375        int support_encode;
00376 
00377        ret = -1;
00378        for (lang_id = 0; lang_id < LANGS_NUM; lang_id++) {
00379               i = 0;
00380               while (1) {
00381                      support_encode = langgroup_info[lang_id].support_encodes[i];
00382                      if (support_encode == ENCODE_ERROR) break;
00383                      if (encodeid == support_encode) {
00384                             ret = lang_id;
00385                             break;
00386                      }
00387                      i++;
00388               }
00389               if (ret != -1) break;
00390        }
00391 
00392        if (ret == -1) 
00393               ret = 0;
00394 
00395        return(langgroup_info[ret].lang_name);
00396 }
00397 
00398 int get_langid_from_locale(char *locale)
00399 {
00400        int lang_id, i, ret;
00401        char *s;
00402 
00403        ret = -1;
00404        for (lang_id = 0; lang_id < LANGS_NUM; lang_id++) {
00405               i = 0;
00406               while (1) {
00407                      s = langgroup_info[lang_id].support_locales[i];
00408                      if (!s || !*s) break;
00409                      if (!strcmp(s, locale)) {
00410                             ret = lang_id;
00411                             break;
00412                      }
00413                      i++;
00414               }
00415               if (ret != -1) break;
00416        }
00417 
00418        if (ret == -1) 
00419               ret = 0;
00420 
00421        return(ret);
00422 }
00423 int get_langid_from_localeid(int localeid)
00424 {
00425        int lang_id, i, ret;
00426        int support_encode;
00427 
00428        ret = -1;
00429        for (lang_id = 0; lang_id < LANGS_NUM; lang_id++) {
00430               i = 0;
00431               while (1) {
00432                      support_encode = langgroup_info[lang_id].support_encodes[i];
00433                      if (support_encode == ENCODE_ERROR) break;
00434                      if (localeid == support_encode) {
00435                             ret = lang_id;
00436                             break;
00437                      }
00438                      i++;
00439               }
00440               if (ret != -1) break;
00441        }
00442 
00443        if (ret == -1) 
00444               ret = 0;
00445 
00446        return(ret);
00447 }
00448 
00449 int get_encodeid_from_name(char *name)
00450 {
00451        int encode_id, i, ret;
00452        char *s;
00453        
00454        ret = -1;
00455        for (encode_id = 0; encode_id < ENCODES_NUM; encode_id++) {
00456               i = 0;
00457               while (1) {
00458                      s = encode_info[encode_id].called_names[i];
00459                      if (!s || !*s) break;
00460                      if (!strcmp(s, name)) {
00461                             ret = encode_id;
00462                             break;
00463                      }
00464                      i++;
00465               }
00466               if (ret != -1) break;
00467        }
00468        if (ret == -1) ret = ENCODE_GB2312; /* return default encode */
00469        return(ret);  
00470 }
00471 
00472 int get_encodeid_from_locale(char *locale)
00473 {
00474        int encode_id, i, ret;
00475        char *s;
00476        
00477        ret = -1;
00478        for (encode_id = 0; encode_id < ENCODES_NUM; encode_id++) {
00479               i = 0;
00480               while (1) {
00481                      s = encode_info[encode_id].support_locales[i];
00482                      if (!s || !*s) break;
00483                      if (!strcmp(s, locale)) {
00484                             ret = encode_id;
00485                             break;
00486                      }
00487                      i++;
00488               }
00489               if (ret != -1) break;
00490        }
00491 
00492        if (ret == -1) ret = ENCODE_ERROR; /* return default encode */
00493 
00494        return(ret);  
00495 }
00496 
00497 char *get_name_from_encodeid(int encode_id)
00498 {
00499        if (encode_id >= 0 && encode_id <= ENCODES_NUM)
00500               return(encode_info[encode_id].called_names[0]);
00501        else
00502               return(NULL);
00503 }
00504 
00505 char *get_default_locale_from_locale(char *locale)
00506 {
00507        int encode_id, i, ret;
00508        char *s;
00509 
00510        ret = -1;
00511        for (encode_id = 0; encode_id < ENCODES_NUM; encode_id++) {
00512               i = 0;
00513               while (1) {
00514                      s = encode_info[encode_id].support_locales[i];
00515                      if (!s || !*s) break;
00516                      if (!strcmp(s, locale)) {
00517                             ret = encode_id;
00518                             break;
00519                      }
00520                      i++;
00521               }
00522               if (ret != -1) break;
00523        }
00524        
00525        if (ret == -1) return(NULL);
00526 
00527        return(encode_info[ret].support_locales[0]);
00528 }
00529 
00530 int  get_char_len_by_encodeid(int encode_id, unsigned char *ch_ptr)
00531 {
00532        int ret = 2;  /* default character length */
00533        unsigned char code0, code1;
00534 
00535        code0 = ch_ptr[0];
00536        if (code0 < 0x80) return(1);
00537 
00538        if (encode_id == ENCODE_UTF8) {
00539               if (code0 > 0xe0)           /* 3 bytes */
00540                      ret = 3;
00541        } else if (encode_id == ENCODE_GB18030) {
00542               code1 = ch_ptr[1];
00543               if (code0 >=0x81 && code0 <= 0xFE) {
00544                      if (code1 >= 0x30 && code1 <= 0x39)
00545                             ret = 4;
00546               } 
00547        } else if (encode_id == ENCODE_EUC_TW) {
00548               if (code0 == 0x8e)          /* 4 bytes */
00549                      ret = 4;
00550        } else if (encode_id == ENCODE_EUC_TH) {
00551               ret = 1;
00552        }
00553 
00554        return(ret);
00555 }
00556 
00557 int is_valid_code(int encode_id, unsigned char *int_code, int code_len)
00558 {
00559        unsigned char code0, code1, code2, code3;
00560        
00561        code0 = int_code[0];
00562        code1 = int_code[1];
00563 
00564        switch (encode_id) {
00565               case ENCODE_GB2312:
00566                      if (code0 < 0xA1 || code0 > 0xFE)
00567                             return (-1);
00568                      if (code1 < 0xA1 || code1 > 0xFE)
00569                             return (-1);
00570                      break;
00571                      
00572               case ENCODE_GBK:
00573                      if (code0 < 0x81 || code0 > 0xFE)
00574                             return (-1);
00575                      if (code1 < 0x40 || code1 > 0xFE || code1 == 0x7F)
00576                             return (-1);
00577                      break;
00578 
00579               case ENCODE_GB18030:
00580                      if (code_len == 2) {
00581                             if (code0 < 0x81 || code0 > 0xFE)
00582                                    return (-1);
00583                             if (code1 < 0x40 || code1 > 0xFE || code1 == 0x7F)
00584                                    return (-1);
00585                      } else if (code_len == 4) {
00586                             code2 = int_code[2];
00587                             code3 = int_code[3];
00588                             if (code0 < 0x81 || code0 > 0xFE)
00589                                    return (-1);
00590                             if (code1 < 0x30 || code1 > 0x39)
00591                                    return (-1);
00592                             if (code2 < 0x81 || code2 > 0xFE)
00593                                    return (-1);
00594                             if (code3 < 0x30 || code3 > 0x39)
00595                                    return (-1);
00596                      }
00597                      break;
00598 
00599               case ENCODE_BIG5:
00600 #if 0
00601                      /* define in lcbig5.c */
00602                      if ((code0 >= 0xA1) && code0 <= 0xC5) || (code0 >= 0xC9 && code0 <= 0xF9)) {
00603                             if (code1 < 0x40 || code1 == 0xFF || (code1 >= 0x7F && code1 <= 0xA0))
00604                                    return (-1);
00605                             else
00606                                    return (0);
00607                      } else {
00608                             if (code0 == 0xC6 && (code1 >= 0x40 && code1 <= 0x7E))
00609                                    return (0);
00610                             else
00611                                    return (-1);
00612                      }
00613 #endif
00614                                    
00615                      if (code0 < 0xA1 || code0 > 0xFE)
00616                             return (-1);
00617                      if (code1 < 0x40 || code1 > 0xFE)
00618                             return (-1);
00619                      if (code1 > 0x7E && code1 < 0xA1)
00620                             return (-1);
00621                      break;
00622 
00623               case ENCODE_EUC_TW:
00624                      if (code_len == 2) {
00625                             if (code0 < 0x80 || code1 <0x80)
00626                                    return (-1);
00627                      } if (code_len == 4) {
00628                             code2 = int_code[2];
00629                             code3 = int_code[3];
00630                             if (code0 != 0x8E)
00631                                    return(-1);
00632                             if (code1 < 0x80 || code2 < 0x80 || code3 < 0x80)
00633                                    return(-1);
00634                      }
00635                      break;
00636 
00637               case ENCODE_BIG5HK:
00638                      if (code0 < 0x81 || code0 > 0xFE)
00639                             return (-1);
00640                      if (code1 < 0x40 || code1 > 0xFE)
00641                             return (-1);
00642                      break;
00643 
00644               case ENCODE_EUC_KO:
00645                      if (code0 < 0xA1 || code0 > 0xFE)
00646                             return (-1);
00647                      if (code1 < 0xA1 || code1 > 0xFE)
00648                             return (-1);
00649                      break;
00650 
00651               case ENCODE_UTF8:
00652                      break;
00653        }
00654        return(0);
00655 }
00656 
00657 int is_valid_encode_string(int encode_id, unsigned char *hzstr, int hzlen)
00658 {
00659        int i, char_len, ret;
00660        unsigned char *ptr;
00661 
00662        i = 0;
00663        while (i < hzlen) {
00664               ptr = hzstr + i;
00665               if (*ptr < 0x80) {
00666                      if (*ptr == 0x3f && i < hzlen-1) {
00667                             if (*(ptr+1) == 0x3f)
00668                                    return(-1);
00669                      }
00670 
00671                      i++;
00672               } else {
00673                      char_len = get_char_len_by_encodeid(encode_id, ptr);
00674                      ret = is_valid_code(encode_id, ptr, char_len);
00675                      if (ret == -1)
00676                             return(-1);
00677                      i += char_len;
00678               }
00679        }
00680 
00681        return (0);
00682 }
00683 
00684 /* iconv functions */
00685 int Convert_Native_To_UTF8(int encode_id, char *from_buf, size_t from_left,
00686                         char **to_buf, size_t * to_left)
00687 {
00688        const char    *ip;
00689        char          *op;
00690        size_t        ileft, oleft;
00691        iconv_t              fd_iconv;
00692        char          *codeset;
00693        size_t        ret = 0;
00694        
00695        if (encode_id < 0 || encode_id >= ENCODES_NUM)
00696               return(-1);
00697 
00698        if ( (from_left < 0) || (*to_left < 0) )
00699               return(-1);
00700 
00701        ip = (const char *) from_buf;
00702        ileft = from_left;
00703 
00704        op = *((char **) to_buf);
00705        oleft = *to_left;
00706 
00707        if (encode_id == ENCODE_UTF8) {
00708               if (ileft > oleft)
00709                      return(-1);
00710               memcpy(op, ip, ileft);
00711               *to_left = oleft - ileft;
00712               return(0);
00713        }
00714 
00715        fd_iconv = encode_info[encode_id].fd_iconv_to_utf8;
00716        if (fd_iconv == (iconv_t)-1) return(-1);
00717 
00718        if (fd_iconv == NULL) {
00719               codeset = encode_info[encode_id].iconv_codeset_name;
00720               fd_iconv = iconv_open("UTF-8", codeset);
00721               encode_info[encode_id].fd_iconv_to_utf8 = fd_iconv;
00722               if ( fd_iconv == (iconv_t) -1 )
00723                      return(-1);
00724        }
00725 
00726        ret = iconv(fd_iconv, &ip, &ileft, &op, &oleft);
00727        if ((ret != 0) && (E2BIG != errno)) {
00728               return(-1);
00729        }
00730        *to_left = oleft;
00731        return(0);
00732 
00733 }
00734 
00735 int Convert_UTF8_To_Native(int encode_id, char *from_buf, size_t from_left,
00736                         char **to_buf, size_t * to_left)
00737 {
00738        const char    *ip;
00739        char          *op;
00740        size_t        ileft, oleft;
00741        iconv_t              fd_iconv;
00742        char          *codeset;
00743        size_t        ret = 0;
00744        
00745        if (encode_id < 0 || encode_id >= ENCODES_NUM)
00746               return(-1);
00747 
00748        if ( (from_left < 0) || (*to_left < 0) )
00749               return(-1);
00750 
00751        ip = (const char *) from_buf;
00752        ileft = from_left;
00753 
00754        op = *((char **) to_buf);
00755        oleft = *to_left;
00756 
00757        if (encode_id == ENCODE_UTF8) {
00758               if (ileft > oleft)
00759                      return(-1);
00760               memcpy(op, ip, ileft);
00761               *to_left = oleft - ileft;
00762               return(0);
00763        }
00764 
00765        fd_iconv = encode_info[encode_id].fd_iconv_from_utf8;
00766        if (fd_iconv == (iconv_t)-1) return(-1);
00767 
00768        if (fd_iconv == NULL) {
00769               codeset = encode_info[encode_id].iconv_codeset_name;
00770               fd_iconv = iconv_open(codeset, "UTF-8");
00771               encode_info[encode_id].fd_iconv_from_utf8 = fd_iconv;
00772               if ( fd_iconv == (iconv_t) -1 )
00773                      return(-1);
00774        }
00775 
00776        ret = iconv(fd_iconv, &ip, &ileft, &op, &oleft);
00777        if ((ret != 0) && (E2BIG != errno)) {
00778               return(-1);
00779        }
00780        *to_left = oleft;
00781        return(0);
00782 }
00783 
00784 #define UTF16_STRLEN    1024
00785        
00786 int Convert_Native_To_UTF16(int encode_id, char *from_buf, size_t from_left,
00787                         char **to_buf, size_t *to_left)
00788 {
00789        const char    *ip;
00790        char          *op;
00791        size_t        ileft, oleft;
00792 
00793        char          *codeset;
00794        iconv_t              fd_iconv_native_to_utf8;
00795 
00796        size_t        ret = 0;
00797        int           skip_native_to_utf8_iconv = 0;
00798 
00799        if (encode_id < 0 || encode_id >= ENCODES_NUM)
00800               return(-1);
00801 
00802        if ( (from_left < 0) || (*to_left < 0) )
00803               return(-1);
00804 
00805        /* Initialize the iconv of utf8_to_ucs2 */
00806        if (fd_iconv_UTF8_to_UTF16 == (iconv_t)-1 )
00807                return(-1);
00808 
00809        if (fd_iconv_UTF8_to_UTF16 == NULL) {
00810               fd_iconv_UTF8_to_UTF16 = iconv_open("UCS-2", "UTF-8");
00811               if (fd_iconv_UTF8_to_UTF16 == (iconv_t)-1 )
00812                      return(-1);
00813        }
00814 
00815        if (encode_id == ENCODE_UTF8)
00816               skip_native_to_utf8_iconv = 1;
00817 
00818        ip = (const char *) from_buf;
00819        ileft = from_left;
00820 
00821        op = *((char **) to_buf);
00822        oleft = *to_left;
00823 
00824        if (!skip_native_to_utf8_iconv) {
00825               char          buffer[UTF16_STRLEN];   /* Fix me! */
00826               const size_t  buf_len = UTF16_STRLEN;
00827               char          *src, *dst;
00828               size_t        src_len, dst_len;
00829 
00830               /* Initialize the iconv of native_to_utf8 */
00831               fd_iconv_native_to_utf8 = encode_info[encode_id].fd_iconv_to_utf8;
00832               if (fd_iconv_native_to_utf8 == (iconv_t)-1) return(-1);
00833 
00834               if (fd_iconv_native_to_utf8 == NULL) {
00835                      codeset = encode_info[encode_id].iconv_codeset_name;
00836                      fd_iconv_native_to_utf8 = iconv_open("UTF-8", codeset);
00837                      encode_info[encode_id].fd_iconv_to_utf8 = fd_iconv_native_to_utf8;
00838                      if ( fd_iconv_native_to_utf8 == (iconv_t) -1 )
00839                             return(-1);
00840               }
00841 
00842               while ((ileft > 0) && (oleft > 0)) {
00843                      dst = buffer;
00844                      dst_len = buf_len;
00845                      ret = iconv(fd_iconv_native_to_utf8, &ip, &ileft, (char **) &dst, &dst_len);
00846                      if ((ret != 0) && (E2BIG != errno)) {
00847                             return(-1);
00848                      }
00849                      src = buffer;
00850                      src_len = buf_len - dst_len;
00851                      ret = iconv(fd_iconv_UTF8_to_UTF16, (const char **) &src, &src_len, &op, &oleft);
00852                      if ((ret != 0) && (E2BIG != errno)) {
00853                             return(-1);
00854                      }
00855               }
00856 
00857        } else {
00858               ret = iconv(fd_iconv_UTF8_to_UTF16, &ip, &ileft, &op, &oleft);
00859               if ((ret != 0) && (E2BIG != errno)) {
00860                       return(-1);
00861               }
00862        }
00863 
00864        if (0xFEFF == **((CARD16 **) to_buf)) {
00865               memmove(*to_buf, *to_buf + 2, *to_left - oleft - 2);
00866               *to_left = (oleft + 2);
00867        } else {
00868               *to_left = oleft;
00869        }
00870 
00871        return(0);
00872 }
00873 
00874 int Convert_UTF16_To_Native(int encode_id, char *from_buf, size_t from_left,
00875                         char **to_buf, size_t * to_left)
00876 {
00877        const char    *ip;
00878        char          *op;
00879        size_t        ileft, oleft;
00880        char          *codeset;
00881        iconv_t              fd_iconv_utf8_to_native;
00882 
00883        size_t        ret = 0;
00884        int           skip_utf8_to_native_iconv = 0;
00885 
00886        if (encode_id < 0 || encode_id >= ENCODES_NUM)
00887               return(-1);
00888 
00889        if ( (from_left < 0) || (*to_left < 0) )
00890               return(-1);
00891 
00892        /* Initialize the iconv of utf8_to_ucs2 */
00893        if (fd_iconv_UTF16_to_UTF8 == (iconv_t)-1 )
00894                return(-1);
00895 
00896        if (fd_iconv_UTF16_to_UTF8 == NULL) {
00897               fd_iconv_UTF16_to_UTF8 = iconv_open("UTF-8", "UCS-2");
00898               if (fd_iconv_UTF16_to_UTF8 == (iconv_t)-1 )
00899                      return(-1);
00900        }
00901 
00902        if (encode_id == ENCODE_UTF8)
00903               skip_utf8_to_native_iconv = 1;
00904 
00905        ip = (const char *) from_buf;
00906        ileft = from_left;
00907 
00908        op = *((char **) to_buf);
00909        oleft = *to_left;
00910 
00911        if (!skip_utf8_to_native_iconv) {
00912               char          buffer[UTF16_STRLEN];   /* Fix me! */
00913               const size_t  buf_len = UTF16_STRLEN;
00914               char          *src, *dst;
00915               size_t        src_len, dst_len;
00916 
00917               /* Initialize the iconv of native_to_utf8 */
00918               fd_iconv_utf8_to_native = encode_info[encode_id].fd_iconv_from_utf8;
00919               if (fd_iconv_utf8_to_native == (iconv_t)-1) return(-1);
00920 
00921               if (fd_iconv_utf8_to_native == NULL) {
00922                      codeset = encode_info[encode_id].iconv_codeset_name;
00923                      fd_iconv_utf8_to_native = iconv_open(codeset, "UTF-8");
00924                      encode_info[encode_id].fd_iconv_from_utf8 = fd_iconv_utf8_to_native;
00925                      if ( fd_iconv_utf8_to_native == (iconv_t) -1 )
00926                             return(-1);
00927               }
00928 
00929               while ((ileft > 0) && (oleft > 0)) {
00930                      dst = buffer;
00931                      dst_len = buf_len;
00932                      ret = iconv(fd_iconv_UTF16_to_UTF8, &ip, &ileft, (char **) &dst, &dst_len);
00933                      if ((ret != 0) && (E2BIG != errno)) {
00934                             return(-1);
00935                      }
00936                      src = buffer;
00937                      src_len = buf_len - dst_len;
00938                      ret = iconv(fd_iconv_utf8_to_native, (const char **) &src, &src_len, &op, &oleft);
00939                      if ((ret != 0) && (E2BIG != errno)) {
00940                             return(-1);
00941                      }
00942               }
00943 
00944        } else {
00945               ret = iconv(fd_iconv_UTF16_to_UTF8, &ip, &ileft, &op, &oleft);
00946               if ((ret != 0) && (E2BIG != errno)) {
00947                       return(-1);
00948               }
00949        }
00950 
00951        *to_left = oleft;
00952 
00953        return(0);
00954 }