Home | History | Annotate | Line # | Download | only in xlibi18n
      1 /*
      2  * Copyright 1992, 1993 by TOSHIBA Corp.
      3  *
      4  * Permission to use, copy, modify, and distribute this software and its
      5  * documentation for any purpose and without fee is hereby granted, provided
      6  * that the above copyright notice appear in all copies and that both that
      7  * copyright notice and this permission notice appear in supporting
      8  * documentation, and that the name of TOSHIBA not be used in advertising
      9  * or publicity pertaining to distribution of the software without specific,
     10  * written prior permission. TOSHIBA make no representations about the
     11  * suitability of this software for any purpose.  It is provided "as is"
     12  * without express or implied warranty.
     13  *
     14  * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
     15  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
     16  * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
     17  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
     18  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
     19  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     20  * SOFTWARE.
     21  *
     22  * Author: Katsuhisa Yano	TOSHIBA Corp.
     23  *			   	mopi (at) osa.ilab.toshiba.co.jp
     24  */
     25 
     26 #ifdef HAVE_CONFIG_H
     27 #include <config.h>
     28 #endif
     29 #include "Xlibint.h"
     30 #include "XlcPubI.h"
     31 #include <X11/Xutil.h>
     32 #include <X11/Xatom.h>
     33 #include "reallocarray.h"
     34 
     35 static XPointer *
     36 alloc_list(
     37     Bool is_wide_char,
     38     int count,
     39     int nitems)
     40 {
     41     if (is_wide_char) {
     42 	wchar_t **wstr_list;
     43 
     44 	wstr_list = Xmallocarray(count, sizeof(wchar_t *));
     45 	if (wstr_list == NULL)
     46 	    return (XPointer *) NULL;
     47 
     48 	*wstr_list = Xmallocarray(nitems, sizeof(wchar_t));
     49 	if (*wstr_list == NULL) {
     50 	    Xfree(wstr_list);
     51 	    return (XPointer *) NULL;
     52 	}
     53 
     54 	return (XPointer *) wstr_list;
     55     } else {
     56 	char **str_list;
     57 
     58 	str_list = Xmallocarray(count, sizeof(char *));
     59 	if (str_list == NULL)
     60 	    return (XPointer *) NULL;
     61 
     62 	*str_list = Xmalloc(nitems);
     63 	if (*str_list == NULL) {
     64 	    Xfree(str_list);
     65 	    return (XPointer *) NULL;
     66 	}
     67 
     68 	return (XPointer *) str_list;
     69     }
     70 }
     71 
     72 static void
     73 copy_list(
     74     Bool is_wide_char,
     75     XPointer text,
     76     XPointer *list,
     77     int count)
     78 {
     79     int length;
     80 
     81     if (is_wide_char) {
     82 	wchar_t *wc_text, *wstr, **wstr_list;
     83 
     84 	wc_text = (wchar_t *) text;
     85 	wstr_list = (wchar_t **) list;
     86 
     87 	for (wstr = *wstr_list; count > 0; count--, wstr_list++) {
     88 	    _Xwcscpy(wstr, wc_text);
     89 	    *wstr_list = wstr;
     90 	    length = _Xwcslen(wstr) + 1;
     91 	    wstr += length;
     92 	    wc_text += length;
     93 	}
     94     } else {
     95 	char *mb_text, *str, **str_list;
     96 
     97 	mb_text = (char *) text;
     98 	str_list = (char **) list;
     99 
    100 	for (str = *str_list; count > 0; count--, str_list++) {
    101 	    strcpy(str, mb_text);
    102 	    *str_list = str;
    103 	    length = (int) strlen(str) + 1;
    104 	    str += length;
    105 	    mb_text += length;
    106 	}
    107     }
    108 }
    109 
    110 static int
    111 _XTextPropertyToTextList(
    112     XLCd lcd,
    113     Display *dpy,
    114     const XTextProperty *text_prop,
    115     const char *to_type,
    116     XPointer **list_ret,
    117     int *count_ret)
    118 {
    119     XlcConv conv = NULL;
    120     const char *from_type;
    121     XPointer from, to, buf;
    122     char *str_ptr, *last_ptr;
    123     Atom encoding;
    124     int from_left, to_left, buf_len, ret, len;
    125     int unconv_num, nitems = text_prop->nitems;
    126     Bool is_wide_char = False, do_strcpy = False;
    127 
    128     if (strcmp(XlcNWideChar, to_type) == 0)
    129 	is_wide_char = True;
    130 
    131     if (nitems <= 0) {
    132 	*list_ret = NULL;
    133 	*count_ret = 0;
    134 	return Success;
    135     }
    136 
    137     if (text_prop->format != 8)
    138 	return XConverterNotFound;
    139 
    140     encoding = text_prop->encoding;
    141     if (encoding == XA_STRING)
    142 	from_type = XlcNString;
    143     else if (encoding == XInternAtom(dpy, "UTF8_STRING", False))
    144 	from_type = XlcNUtf8String;
    145     else if (encoding == XInternAtom(dpy, "COMPOUND_TEXT", False))
    146 	from_type = XlcNCompoundText;
    147     else if (encoding == XInternAtom(dpy, XLC_PUBLIC(lcd, encoding_name), False))
    148 	from_type = XlcNMultiByte;
    149     else
    150 	return XConverterNotFound;
    151 
    152     if (is_wide_char) {
    153 	buf_len = (text_prop->nitems + 1) * sizeof(wchar_t);
    154     } else {
    155 	if (strcmp(to_type, XlcNUtf8String) == 0)
    156 	    buf_len = text_prop->nitems * 6 + 1;
    157 	else
    158 	    buf_len = text_prop->nitems * XLC_PUBLIC(lcd, mb_cur_max) + 1;
    159     }
    160     buf = Xmalloc(buf_len);
    161     if (buf == NULL)
    162 	return XNoMemory;
    163     to = buf;
    164     to_left = buf_len;
    165 
    166     /* can be XlcNMultiByte to XlcNMultiByte,
    167        or XlcNUtf8String to XlcNUtf8String */
    168     if (!strcmp(from_type, to_type)) {
    169         do_strcpy = True;
    170     } else {
    171         conv = _XlcOpenConverter(lcd, from_type, lcd, to_type);
    172         if (conv == NULL) {
    173 	    Xfree(buf);
    174 	    return XConverterNotFound;
    175         }
    176     }
    177 
    178     last_ptr = str_ptr = (char *) text_prop->value;
    179     unconv_num = *count_ret = 0;
    180 
    181     while (1) {
    182 	if (nitems == 0 || *str_ptr == 0) {
    183 	    from = (XPointer) last_ptr;
    184 	    from_left = str_ptr - last_ptr;
    185 	    last_ptr = str_ptr;
    186 
    187             if (do_strcpy) {
    188             	len = min(from_left, to_left);
    189                 strncpy(to, from, (size_t) len);
    190                 from += len;
    191                 to += len;
    192                 from_left -= len;
    193                 to_left -= len;
    194                 ret = 0;
    195             } else {
    196 	        ret = _XlcConvert(conv, &from, &from_left, &to, &to_left, NULL, 0);
    197             }
    198 
    199 	    if (ret < 0)
    200 		continue;
    201 
    202 	    unconv_num += ret;
    203 	    (*count_ret)++;
    204 
    205 	    if (nitems == 0)
    206 		break;
    207  	    last_ptr = ++str_ptr;
    208 	    if (is_wide_char) {
    209 		*((wchar_t *)to) = (wchar_t) 0;
    210 		to += sizeof(wchar_t);
    211 		to_left -= sizeof(wchar_t);
    212 	    } else {
    213 		*((char *)to) = '\0';
    214 		to++;
    215 		to_left--;
    216 	    }
    217 	    if (! do_strcpy)
    218 	        _XlcResetConverter(conv);
    219 	} else
    220 	    str_ptr++;
    221 
    222 	nitems--;
    223     }
    224 
    225     if (! do_strcpy)
    226         _XlcCloseConverter(conv);
    227 
    228     if (is_wide_char) {
    229 	*((wchar_t *) to) = (wchar_t) 0;
    230 	to_left -= sizeof(wchar_t);
    231     } else {
    232 	*((char *) to) = '\0';
    233 	to_left--;
    234     }
    235 
    236     *list_ret = alloc_list(is_wide_char, *count_ret, buf_len - to_left);
    237     if (*list_ret)
    238 	copy_list(is_wide_char, buf, *list_ret, *count_ret);
    239 
    240     Xfree(buf);
    241 
    242     return unconv_num;
    243 }
    244 
    245 int
    246 _XmbTextPropertyToTextList(
    247     XLCd lcd,
    248     Display *dpy,
    249     const XTextProperty *text_prop,
    250     char ***list_ret,
    251     int *count_ret)
    252 {
    253     return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNMultiByte,
    254 				    (XPointer **) list_ret, count_ret);
    255 }
    256 
    257 int
    258 _XwcTextPropertyToTextList(
    259     XLCd lcd,
    260     Display *dpy,
    261     const XTextProperty *text_prop,
    262     wchar_t ***list_ret,
    263     int *count_ret)
    264 {
    265     return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNWideChar,
    266 				    (XPointer **) list_ret, count_ret);
    267 }
    268 
    269 int
    270 _Xutf8TextPropertyToTextList(
    271     XLCd lcd,
    272     Display *dpy,
    273     const XTextProperty *text_prop,
    274     char ***list_ret,
    275     int *count_ret)
    276 {
    277     return _XTextPropertyToTextList(lcd, dpy, text_prop, XlcNUtf8String,
    278 				    (XPointer **) list_ret, count_ret);
    279 }
    280 
    281 void
    282 _XwcFreeStringList(
    283     XLCd lcd,
    284     wchar_t **list)
    285 {
    286     if (list) {
    287         Xfree(*list);
    288         Xfree(list);
    289     }
    290 }
    291