Back to index

im-sdk  12.3.91
xaux_ext_conv.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2003 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 
00043 #pragma ident "$Id$"
00044 
00045 #include "iiimpAux.h"
00046 
00047 #if 0
00048 #ifdef linux
00049 #define USE_CSCONV
00050 #endif
00051 #endif /* 0 */
00052 
00053 #if !defined(USE_ICONV) && !defined(USE_CSCONV)
00054 #if defined(sun)
00055 #define USE_ICONV
00056 #else
00057 #define USE_CSCONV
00058 #endif
00059 #endif
00060 
00061 #ifdef USE_ICONV
00062 #include <iconv.h> 
00063 #endif
00064 
00065 #include <locale.h>
00066 #include <langinfo.h>
00067 #include <strings.h>
00068 #if !defined(USE_CSCONV)
00069 #include <errno.h>
00070 #endif /* !USE_CSCONV */
00071 #if 0
00072 #include "iiimpIM.h"
00073 #include "iiimp.h"
00074 #include "iiimpReq.h"
00075 #endif
00076 
00077 #define UTF16_STRLEN 4096
00078 
00079 #ifdef USE_CSCONV
00080 #include <dlfcn.h>
00081 #include "csconv.h"
00082 #define CSC_OPEN_LOCALE     "csconv_open_locale"
00083 #define CSC_OPEN     "csconv_open"
00084 #define CSC_CONV     "csconv"
00085 #define CSC_CLOSE    "csconv_close"
00086 
00087 typedef csconv_t     (* csc_open_locale_t)(const char *,
00088                                          const char *, const char *);
00089 typedef csconv_t     (* csc_open_t)(const char *, const char *);
00090 typedef size_t              (* csc_conv_t)(csconv_t, const char **, size_t *,
00091                                    char **, size_t *);
00092 typedef int          (* csc_close_t)(csconv_t);
00093 
00094 static void *               csc_handle;   
00095 static csc_open_locale_t    csc_open_locale;
00096 static csc_open_t           csc_open;
00097 static csc_conv_t           csc_conv;
00098 static csc_close_t          csc_close;
00099 
00100 static char *current_locale = 0;
00101 #endif
00102 
00103 #ifdef USE_ICONV
00104 static iconv_t i_conv1 = NULL;
00105 static iconv_t i_conv2 = NULL;
00106 static Bool skip_native_to_utf8_conv = False;
00107 #endif
00108 
00109 #ifdef USE_CSCONV
00110 static void
00111 dlopen_csconv()
00112 {
00113       csc_handle = dlopen(CSC_PATH, RTLD_LAZY);
00114       if (NULL == csc_handle) {
00115         csc_handle = (void *)(-1);
00116        return;
00117       }
00118 
00119       csc_open_locale = (csc_open_locale_t)dlsym(csc_handle, CSC_OPEN_LOCALE);
00120       csc_open = (csc_open_t)dlsym(csc_handle, CSC_OPEN);
00121       csc_conv = (csc_conv_t)dlsym(csc_handle, CSC_CONV);
00122       csc_close = (csc_close_t)dlsym(csc_handle, CSC_CLOSE);
00123 
00124       if ((NULL == csc_open_locale) || (NULL == csc_open) ||
00125          (NULL == csc_conv) || (NULL == csc_close)) {
00126         dlclose(csc_handle);
00127        csc_handle = (void *)(-1);
00128        return;
00129       }
00130 }
00131 #endif
00132 
00133 static int
00134 IIimpConvertToUTF16(char *from_buf, size_t from_left,
00135                   char **to_buf, size_t *to_left) {
00136   size_t src_len, dst_len;
00137   char *src, *dst;
00138 #ifndef USE_CSCONV
00139   const char *ip;
00140   size_t ileft;
00141   char *op;
00142   size_t oleft;
00143   char buffer[UTF16_STRLEN];              /* Fix me! */
00144 #endif /* !USE_CSCONV */
00145   const size_t buf_len = UTF16_STRLEN;
00146   size_t ret = 0;
00147 #ifdef USE_CSCONV
00148   static csconv_t csconv_cd = NULL;
00149 
00150 #endif
00151 
00152 #ifdef USE_CSCONV
00153   if (current_locale == NULL){
00154     current_locale = (char*)strdup(setlocale(LC_CTYPE, NULL));
00155   }
00156 
00157   do {
00158     if (((void *)(-1) == csc_handle) ||
00159        ((csconv_t)(-1) == csconv_cd)) {
00160       continue;
00161     }
00162     if (NULL == csc_handle) {
00163       dlopen_csconv();
00164       if ((void *)(-1) == csc_handle) {
00165        continue;
00166       }
00167     }
00168     if (NULL == csconv_cd) {
00169 
00170       csconv_cd = (csc_open_locale)(current_locale, "UTF-16", "MultiByte");
00171       
00172       if ((csconv_t)(-1) == csconv_cd) {
00173        continue;
00174       }
00175     }
00176 
00177     dst = *((char **)to_buf);
00178 
00179     ret = csc_conv(csconv_cd,
00180                  (const char **)&from_buf, (size_t*)&from_left,
00181                  &dst, to_left);
00182     return ret;
00183   } while (0);
00184 #endif
00185 
00186 #ifdef USE_ICONV
00187   if (i_conv1 == (iconv_t)-1 || i_conv2 == (iconv_t)-1){
00188     goto done;
00189   }
00190 
00191   if (i_conv1 == NULL && !skip_native_to_utf8_conv) {
00192     char *encoding = nl_langinfo(CODESET);
00193     if (!strcmp(encoding, "UTF-8")) {
00194       skip_native_to_utf8_conv = True;
00195     } else {
00196       if ((i_conv1 = iconv_open("UTF-8", encoding))
00197          == (iconv_t)-1) {
00198        goto done;
00199       }
00200     }
00201   }
00202 
00203   if (i_conv2 == NULL){
00204     if ((i_conv2 = iconv_open("UCS-2",
00205                            "UTF-8")) == (iconv_t)-1)
00206       goto done;
00207   }
00208 
00209   if (!skip_native_to_utf8_conv) {
00210     ip = (const char *)from_buf;
00211     ileft = from_left;
00212 
00213     op = *((char **)to_buf);
00214     oleft = (size_t)(*to_left);
00215 
00216     while ((0 < ileft) && (0 < oleft)) {
00217       dst = buffer;
00218       dst_len = buf_len;
00219       ret = iconv(i_conv1, &ip, &ileft, (char**)&dst, &dst_len);
00220       if ((ret != 0) && (E2BIG != errno)) {
00221        goto done;
00222       }
00223 
00224       src = buffer;
00225       src_len = buf_len - dst_len;
00226 
00227       ret = iconv(i_conv2, (const char**)&src, (size_t*)&src_len,
00228                 &op, &oleft);
00229       if (ret != 0) goto done;
00230     }
00231 
00232     dst_len = oleft;
00233 
00234   } else {
00235     src = from_buf;
00236     src_len = from_left;
00237     dst = *to_buf;
00238     dst_len = *to_left;
00239     ret = iconv(i_conv2, (const char**)&src, (size_t*)&src_len,
00240               (char**)&dst, &dst_len);
00241   }
00242 
00243   if (0xFEFF == **((CARD16 **)to_buf)) {
00244     memmove(*to_buf, *to_buf + 2, *to_left - dst_len - 2);
00245     *to_left = (dst_len + 2);
00246   } else {
00247     *to_left = dst_len;
00248   }
00249 done:
00250 #endif /* USE_ICONV */
00251   return(ret);
00252 }
00253 
00254 #ifdef USE_ICONV
00255 static iconv_t i_conv1_FromUTF16 = NULL;
00256 static iconv_t i_conv2_FromUTF16 = NULL;
00257 #endif
00258 
00259 /* Used when transfering data from AUX to IM,
00260    do data conversion from UCS2 to EUC */
00261 static int
00262 IIimpConvertFromUTF16(char *from_buf, size_t from_left,
00263                     char **to_buf, size_t * to_left) {
00264   size_t src_len, dst_len;
00265   char *src, *dst;
00266 #ifndef USE_CSCONV
00267   const char *ip;
00268   size_t ileft;
00269   char *op;
00270   size_t oleft;
00271   char buffer[UTF16_STRLEN];       /* Fix me! */
00272 #endif /* !USE_CSCONV */
00273   const size_t buf_len = UTF16_STRLEN;
00274   size_t ret = 0;
00275 
00276 #ifdef USE_CSCONV
00277   static csconv_t csconv_cd = NULL;
00278 #endif
00279 
00280 #ifdef USE_CSCONV
00281   do {
00282     if (((void *)(-1) == csc_handle) ||
00283        ((csconv_t)(-1) == csconv_cd)) {
00284       continue;
00285     }
00286     if (NULL == csc_handle) {
00287       dlopen_csconv();
00288       if ((void *)(-1) == csc_handle) {
00289        continue;
00290       }
00291     }
00292     if (NULL == csconv_cd) {
00293 
00294       csconv_cd = (csc_open_locale)(current_locale, "MultiByte", "UTF-16");
00295       
00296       if ((csconv_t)(-1) == csconv_cd) {
00297        continue;
00298       }
00299     }
00300 
00301     dst = *((char **)to_buf);
00302 
00303     ret = csc_conv(csconv_cd,
00304                  (const char **)&from_buf, (size_t*)&from_left,
00305                  &dst, to_left);
00306     return ret;
00307   } while (0);
00308 #endif
00309 
00310 #ifdef USE_ICONV
00311   if (i_conv1_FromUTF16 == (iconv_t)-1 ||
00312       i_conv2_FromUTF16 == (iconv_t)-1) {
00313     goto done;
00314   }
00315 
00316   if (i_conv2_FromUTF16 == NULL && !skip_native_to_utf8_conv) {
00317     char *encoding = nl_langinfo(CODESET);
00318     if (!strcmp(encoding, "UTF-8")) {
00319       skip_native_to_utf8_conv = True;
00320     } else {
00321       if ((i_conv2_FromUTF16 = iconv_open(encoding, "UTF-8"))
00322          == (iconv_t) - 1) {
00323        goto done;
00324       }
00325     }
00326   }
00327   if (i_conv1_FromUTF16 == NULL) {
00328     if ((i_conv1_FromUTF16 = iconv_open("UTF-8", "UCS-2"))
00329        == (iconv_t) - 1) {
00330       goto done;
00331     }
00332   }
00333 
00334   if (skip_native_to_utf8_conv) {
00335     src = from_buf;
00336     src_len = from_left;    /* don't stop at '\0' in case of ascii */
00337     dst = *((char **) to_buf);
00338     ret = iconv(i_conv1_FromUTF16, (const char**)&src, (size_t*)&src_len,
00339               (char**)&dst, (size_t*)to_left);
00340   } else {
00341     ip = (const char *)from_buf;
00342     ileft = from_left;
00343 
00344     op = *((char **)to_buf);
00345     oleft = (size_t)(*to_left);
00346 
00347     while ((0 < ileft) && (0 < oleft)) {
00348       dst = buffer;
00349       dst_len = buf_len;
00350       ret = iconv(i_conv1_FromUTF16, &ip, &ileft, (char**)&dst, &dst_len);
00351       if ((ret != 0) && (E2BIG != errno)) {
00352        goto done;
00353       }
00354 
00355       src = buffer;
00356       src_len = buf_len - dst_len;
00357 
00358       ret = iconv(i_conv2_FromUTF16, (const char**)&src, (size_t*)&src_len,
00359                 &op, &oleft);
00360       if (ret != 0) goto done;
00361     }
00362 
00363     *to_left = oleft;
00364   }
00365 done:
00366 #endif /* USE_ICONV */
00367   return(ret);
00368 }
00369 
00370 /* from iiimpAux.c */
00371 size_t
00372 utf16_mb(
00373         const char **   inbuf,
00374         size_t *        inbytesleft,
00375         char **         outbuf,
00376         size_t *        outbytesleft)
00377 {
00378         int     r;
00379 
00380         r = IIimpConvertFromUTF16((char *)(*inbuf), *inbytesleft,
00381                                   outbuf, outbytesleft);
00382         return (size_t)r;
00383 }
00384 
00385 size_t
00386 mb_utf16(
00387         const char **   inbuf,
00388         size_t *        inbytesleft,
00389         char **         outbuf,
00390         size_t *        outbytesleft)
00391 {
00392         int     r;
00393 
00394         r = IIimpConvertToUTF16((char *)(*inbuf), *inbytesleft,
00395                                   outbuf, outbytesleft);
00396         return (size_t)r;
00397 }