2 * Copyright © 1996, 2015, Oracle and/or its affiliates. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
30 #include "XlcGeneric.h"
33 * codesets will derived from XLC_XLOCALE and codesets[0] is
34 * gb18030.2000-1 in XLC_XLOCALE
36 #define CS0 codesets[2] /* Codeset 0 - 7-bit ASCII */
37 #define CS1 codesets[0] /* Codeset 1 - gb18030.2000-0 */
38 #define CS2 codesets[1] /* Codeset 2 - gb18030.2000-1 */
40 #define ascii (codeset->cs_num == 0)
41 #define gb18030 (codeset->cs_num == 2)
43 #define ASCII_CODESET 0
44 #define GBK2K_CODESET1 1
45 #define GBK2K_CODESET2 2
46 #define MAX_CODESETS 3
48 #define ISASCII(ch) ((unsigned char)(ch) <= 0x7F)
50 #define GR 0x80 /* Begins right-side (non-ascii) region. */
51 #define GL 0x7f /* Ends left-side (ascii) region. */
53 #define isleftside(c) (((c) & GR) ? 0 : 1)
54 #define isrightside(c) (! isleftside(c))
56 typedef unsigned char Uchar
;
57 typedef unsigned long Ulong
;
58 typedef unsigned int Uint
;
60 #define BIT8OFF(c) ((c) & GL)
61 #define BIT8ON(c) ((c) | GR)
65 typedef struct _CT_DATA
71 static CT_DATA default_ct_data
[] =
74 {"GB2312", "\033$(A" },
75 {"GB18030-0", "\033%/2??SUN-GB18030-0" },
76 {"GB18030-1", "\033%/2??SUN-GB18030-1" }
79 static int num_ct_data
= sizeof(default_ct_data
)/sizeof(CT_DATA
);
82 get_CT_encode_string(const char *charset
)
87 for (i
=0; i
< num_ct_data
; ++i
)
89 default_ct_data
[i
].charset
,
90 strlen(charset
)) == 0)
91 return default_ct_data
[i
].encode_string
;
97 typedef enum {t_ASCII
, t_GB2312
, t_GB18030_0
, t_GB18030_1
, t_NONE
} CharSet_Type
;
100 get_charset_with_encode_string(const char *s
)
105 for (i
=0; i
< num_ct_data
; ++i
)
106 if (strncmp(s
, default_ct_data
[i
].encode_string
,
107 strlen(default_ct_data
[i
].encode_string
)) == 0)
115 twobyte_to_fourbyte(unsigned char *in_buf
, unsigned char *out_buf
)
119 tmp
=(in_buf
[0] << 8) + in_buf
[1];
121 out_buf
[3] = 0x30 + tmp
%10; tmp
/=10;
122 out_buf
[2] = 0x81 + tmp
%126; tmp
/=126;
123 out_buf
[1] = 0x30 + tmp
%10; tmp
/=10;
124 out_buf
[0] = 0x81 + tmp
;
128 fourbyte_to_twobyte(unsigned char *in_buf
, unsigned char *out_buf
)
132 tmp
= 12600 * (in_buf
[0] - 0x81) + 1260 * (in_buf
[1] - 0x30) +
133 10 * (in_buf
[2] - 0x81) + (in_buf
[3] - 0x30);
134 out_buf
[0] = (tmp
& 0xff00) >> 8;
135 out_buf
[1] = tmp
& 0xff;
139 * In GB2312 range or not
142 isgb(unsigned char *s
)
144 /* consider the first byte */
145 if (s
[0] >= 0xA1 && s
[0] <= 0xFE && s
[1] >= 0xA1 &&
154 * In GB18030 2 bytes range or not
157 isgb18030_2(unsigned char *s
)
159 /* consider the first byte */
160 if (s
[0] >= 0x81 && s
[0] <= 0xfe &&
161 ((s
[1] >= 0x40 && s
[1] <= 0x7e) ||
162 (s
[1] >= 0x80 && s
[1] <= 0xfe)))
169 * In GB18030 4 bytes range or not
171 static int isgb18030_4(unsigned char *s
)
173 /* consider the first byte */
174 if (s
[0] >= 0x81 && s
[0] <= 0xfe && s
[1] >= 0x30 && s
[1] <= 0x39 &&
175 s
[2] >= 0x81 && s
[2] <= 0xfe && s
[3] >= 0x30 && s
[3] <= 0x39)
182 * multibyte -> charset: codesets[0], codesets[1], codeset[2]
194 unsigned char *src
= (unsigned char *)*from
;
195 unsigned char *dst
= (unsigned char *)*to
;
198 XLCd lcd
= (XLCd
)conv
->state
;
199 CodeSet
*codesets
= XLC_GENERIC(lcd
, codeset_list
);
200 int codeset_num
= XLC_GENERIC(lcd
, codeset_num
);
201 XlcCharSet charset
= NULL
;
203 if (isgb18030_2(src
)) {
204 if (GBK2K_CODESET1
>= codeset_num
)
206 charset
= *CS1
->charset_list
;
207 char_size
= charset
->char_size
;
209 if (*from_left
>= 2 && *to_left
>= char_size
) {
216 *from_left
-= char_size
;
217 *to_left
-= char_size
;
218 } else if (isgb18030_4(src
)) {
219 unsigned char iconv_buf
[6];
221 if (GBK2K_CODESET2
>= codeset_num
)
224 charset
= *CS2
->charset_list
;
225 char_size
= charset
->char_size
;
226 fourbyte_to_twobyte(src
, iconv_buf
);
227 if (*from_left
>= 4 && *to_left
>= char_size
) {
228 *dst
++ = iconv_buf
[0];
229 *dst
++ = iconv_buf
[1];
236 *to_left
-= char_size
;
237 } else if (ISASCII(*src
)) {
238 if (ASCII_CODESET
>= codeset_num
)
240 charset
= *CS0
->charset_list
;
241 char_size
= charset
->char_size
;
243 if (*from_left
>= char_size
&& *to_left
>= char_size
)
248 *from_left
-= char_size
;
249 *to_left
-= char_size
;
250 } else { /* unknown */
257 *from
= (XPointer
)src
;
260 *((XlcCharSet
*) args
[0]) = charset
;
275 unsigned char *src
= (unsigned char *)*from
;
276 unsigned char *dst
= (unsigned char *)*to
;
280 XLCd lcd
= (XLCd
)conv
->state
;
281 CodeSet
*codesets
= XLC_GENERIC(lcd
, codeset_list
);
282 int codeset_num
= XLC_GENERIC(lcd
, codeset_num
);
283 XlcCharSet charset
= NULL
;
286 if (isgb18030_2(src
)) {
289 if (flag
== 3 || flag
== 2 )
291 if (GBK2K_CODESET1
>= codeset_num
)
294 charset
= *CS1
->charset_list
;
295 char_size
= charset
->char_size
;
297 if (*from_left
>= char_size
&& *to_left
>= char_size
) {
300 *to_left
-= char_size
;
301 *from_left
-= char_size
;
305 } else if (isgb18030_4(src
)) {
306 unsigned char iconv_buf
[6];
310 if (flag
== 3 || flag
== 1)
312 if (GBK2K_CODESET2
>= codeset_num
)
315 charset
= *CS2
->charset_list
;
316 char_size
= charset
->char_size
;
317 fourbyte_to_twobyte(src
, iconv_buf
);
319 if (*from_left
>= 4 && *to_left
>= char_size
) {
320 *dst
++ = iconv_buf
[0];
321 *dst
++ = iconv_buf
[1];
323 *to_left
-= char_size
;
328 } else if (ISASCII(*src
)) {
331 if (flag
== 1 || flag
==2 )
333 if (ASCII_CODESET
>= codeset_num
)
336 charset
= *CS0
->charset_list
;
337 char_size
= charset
->char_size
;
338 if (*from_left
>= char_size
&& *to_left
>= char_size
) {
340 *to_left
-= char_size
;
341 *from_left
-= char_size
;
345 } else{ /* unknown */
355 *from
= (XPointer
)src
;
359 *((XlcCharSet
*) args
[0]) = charset
;
374 unsigned char *dst
= (unsigned char *)*to
;
375 wchar_t *src
= (wchar_t *)*from
;
379 XLCd lcd
= (XLCd
)conv
->state
;
380 XlcCharSet charset
= NULL
;
381 CodeSet
*codesets
= XLC_GENERIC(lcd
, codeset_list
);
382 int codeset_num
= XLC_GENERIC(lcd
, codeset_num
);
384 charset
= (XlcCharSet
)args
[0];
392 if (isgb18030_2((unsigned char*)tmp
)) {
395 if (flag
== 2 || flag
== 3)
397 if (GBK2K_CODESET1
>= codeset_num
)
400 charset
= *CS1
->charset_list
;
401 char_size
= charset
->char_size
;
403 if (*from_left
> 0 && *to_left
>= char_size
) {
406 *to_left
-= char_size
;
410 } else if (isgb18030_4((unsigned char*)tmp
)) {
411 unsigned char iconv_buf
[6];
415 if (flag
== 1 || flag
== 3)
417 if (GBK2K_CODESET2
>= codeset_num
)
420 charset
= *CS2
->charset_list
;
421 char_size
= charset
->char_size
;
422 fourbyte_to_twobyte((unsigned char*)tmp
, iconv_buf
);
424 if (*from_left
> 0 && *to_left
>= char_size
) {
425 *dst
++ = iconv_buf
[0];
426 *dst
++ = iconv_buf
[1];
427 *to_left
-= char_size
;
431 } else if (ISASCII(tmp
[0])) {
434 if (flag
== 1 || flag
== 2)
436 if (ASCII_CODESET
>= codeset_num
)
439 charset
= *CS0
->charset_list
;
440 char_size
= charset
->char_size
;
441 if (*from_left
> 0 && *to_left
>= char_size
) {
443 *to_left
-= char_size
;
447 } else { /* unknown */
451 src
++; /* advance one wchar_t */
457 *from
= (XPointer
)src
;
461 *((XlcCharSet
*)args
[0]) = charset
;
467 get_code_set_from_charset(
471 CodeSet
*codeset
= XLC_GENERIC(lcd
, codeset_list
);
472 XlcCharSet
*charset_list
;
473 int codeset_num
, num_charsets
;
475 codeset_num
= XLC_GENERIC(lcd
, codeset_num
);
477 for (; codeset_num
-- > 0; codeset
++) {
478 num_charsets
= (*codeset
)->num_charsets
;
479 charset_list
= (*codeset
)->charset_list
;
481 for (; num_charsets
-- > 0; charset_list
++)
482 if (*charset_list
== charset
)
486 return (CodeSet
)NULL
;
499 unsigned char *src
= (unsigned char *)*from
;
500 unsigned char *dst
= (unsigned char *)*to
;
503 XLCd lcd
= (XLCd
)conv
->state
;
504 XlcCharSet charset
= (XlcCharSet
) args
[0];
507 codeset
= get_code_set_from_charset(lcd
, charset
);
512 if (codeset
->wc_encoding
==0x5e84) { /* GB18030-1 */
515 if (*from_left
>= 2 && *to_left
>= 4) {
516 unsigned char iconv_buf
[6];
518 twobyte_to_fourbyte(src
, iconv_buf
);
519 *dst
++ = iconv_buf
[0];
520 *dst
++ = iconv_buf
[1];
521 *dst
++ = iconv_buf
[2];
522 *dst
++ = iconv_buf
[3];
527 } else if (isgb18030_2((unsigned char*)src
)) { /*2 bytes character*/
530 if (*from_left
>= 2 && *to_left
>= 2) {
537 } else if (ISASCII(*src
)) { /*ASCII character*/
540 if (*from_left
>= 1 && *to_left
>= 1) {
546 } else { /* unknown */
552 *from_left
-= char_size
;;
557 *from
= (XPointer
)src
;
558 *to
= (XPointer
)dst
;
561 *((XlcCharSet
*) args
[0]) = charset
;
576 XPointer outbufptr
, outbufptr_save
;
577 int to_left_save
= *to_left
;
578 wchar_t *pwc
= (wchar_t *) *to
;
581 outbufptr
= (XPointer
) Xmalloc(*to_left
* 4);
582 outbufptr_save
= outbufptr
;
584 rtn
= gb18030_cstombs(conv
, from
, from_left
,
589 rtn_1
= mbstowcs(pwc
, outbufptr_save
, (to_left_save
- *to_left
));
591 Xfree(outbufptr_save
);
593 *to_left
= to_left_save
- rtn_1
;
594 *to
= *to
+ rtn_1
* sizeof(wchar_t);
601 * In gb18030 locale, we only consider the following possibilities
602 * all other ct formats are ignored, keep looping until end of buffer
618 unsigned char *inbufptr
= (unsigned char *)*from
;
619 unsigned char *outbufptr
= (unsigned char *)*to
;
622 int save_outbuf
= True
;
623 CharSet_Type charset_type
;
626 * If outbufptr is NULL, doen't save output, but just counts
627 * a length to hold the output.
629 if (outbufptr
== NULL
)
635 while (i
< *from_left
) {
636 if (inbufptr
[i
] == ESC
) { /* got an escape */
637 charset_type
= get_charset_with_encode_string(
638 (const char *)inbufptr
+ i
);
640 switch (charset_type
) {
642 i
+= strlen(default_ct_data
[charset_type
].encode_string
);
645 if (i
>= *from_left
) { /* end of from buffer */
649 if ((inbufptr
[i
] == 0x0a || inbufptr
[i
] == 0x09 ||
650 inbufptr
[i
] >= 0x20) && ISASCII(inbufptr
[i
])) {
651 if (*to_left
< 1) { /* end of to buffer */
655 if (save_outbuf
== True
)
656 outbufptr
[j
++] = inbufptr
[i
];
667 i
+= strlen(default_ct_data
[charset_type
].encode_string
);
670 unsigned char iconv_buf
[3];
672 if (i
>= *from_left
) { /* end of from buffer */
676 iconv_buf
[0] = (inbufptr
[i
] & 0x7f) | 0x80;
677 iconv_buf
[1] = (inbufptr
[i
+ 1] & 0x7f) | 0x80;
679 if (isgb(iconv_buf
)) {
680 if (*to_left
< 2 || *from_left
< 2) {
684 if (save_outbuf
== True
) {
685 outbufptr
[j
++] = iconv_buf
[0];
686 outbufptr
[j
++] = iconv_buf
[1];
698 i
+= strlen(default_ct_data
[charset_type
].encode_string
);
701 if (i
>= *from_left
) { /* end of from buffer */
705 if (isgb18030_2(inbufptr
+ i
)) {
706 if (*to_left
< 2 || *from_left
< 2) {
710 if (save_outbuf
== True
) {
711 outbufptr
[j
++] = inbufptr
[i
];
712 outbufptr
[j
++] = inbufptr
[i
+ 1];
723 case t_GB18030_1
: /* gb18030.2000-1 character */
724 i
+= strlen(default_ct_data
[charset_type
].encode_string
);
727 if (i
>= *from_left
) { /* end of from buffer */
731 if (isgb18030_4(inbufptr
+ i
)) {
732 if (*to_left
< 4 || *from_left
< 4) {
736 if (save_outbuf
== True
) {
737 outbufptr
[j
++] = inbufptr
[i
] & 0xff;
738 outbufptr
[j
++] = inbufptr
[i
+1] & 0xff;
739 outbufptr
[j
++] = inbufptr
[i
+2] & 0xff;
740 outbufptr
[j
++] = inbufptr
[i
+3] & 0xff;
752 i
++; /* encounter unknown escape sequence */
756 } else if ((inbufptr
[i
] == 0x0a || inbufptr
[i
] == 0x09 ||
757 inbufptr
[i
] >= 0x20) && ISASCII(inbufptr
[i
])) {
758 /* Process default CT G0 ascii character */
763 if (save_outbuf
== True
)
764 outbufptr
[j
++] = inbufptr
[i
];
768 } else { /* unknown character */
775 *from
= (XPointer
)(inbufptr
+ i
);
776 *to
= (XPointer
)(outbufptr
+ j
);
795 XPointer outbufptr
, outbufptr_end
;
796 int to_left_save
= *to_left
;
797 wchar_t *pwc
= (wchar_t *) *to
;
801 outbufptr
= (XPointer
) Xmalloc(*to_left
* 4); /* 100 safty tolerence */
802 outbufptr_end
= outbufptr
;
804 rtn
= gb18030_ctstombs(conv
,
812 *outbufptr_end
= '\0';
814 rtn_1
= mbstowcs(pwc
, outbufptr
, (to_left_save
- *to_left
));
818 *to_left
= to_left_save
- rtn_1
;
819 *to
= *to
+ rtn_1
* sizeof(wchar_t);
825 * The mbs is GB18030 code, must be converted to euc code,
826 * then pack to ct format.
838 unsigned char *inbufptr
= (unsigned char *)*from
;
839 unsigned char *outbufptr
= (unsigned char *)*to
;
841 int flag
= 0, j
= 0, i
= 0;
842 int encode_string_len
;
845 while (i
< *from_left
&& j
< *to_left
) {
846 if (isgb(&inbufptr
[i
])) { /* GB2312 character */
847 if (flag
== 0 || flag
!= 2) {
848 encode_string
= get_CT_encode_string("GB2312");
849 if (! encode_string
)
852 encode_string_len
= strlen(encode_string
);
853 if (j
+ encode_string_len
+ 2 >= *to_left
)
856 strncpy((char *)outbufptr
+j
, encode_string
, encode_string_len
);
857 j
+= encode_string_len
;
861 if (j
+ 2 >= *to_left
)
864 outbufptr
[j
++] = inbufptr
[i
++] & 0x7f;
865 outbufptr
[j
++] = inbufptr
[i
++] & 0x7f;
866 } else if (isgb18030_2(&inbufptr
[i
])) { /* 2 bytes GB 18030 */
867 if (flag
== 0 || flag
!= 4) {
868 encode_string
= get_CT_encode_string("GB18030-0");
869 if (! encode_string
)
872 encode_string_len
= strlen(encode_string
);
873 if (j
+ encode_string_len
+ 2 >= *to_left
)
876 strncpy((char *)outbufptr
+j
, encode_string
, encode_string_len
);
877 j
+= encode_string_len
;
881 if (j
+ 2 >= *to_left
)
884 outbufptr
[j
++] = inbufptr
[i
++] & 0xff;
885 outbufptr
[j
++] = inbufptr
[i
++] & 0xff;
886 } else if (isgb18030_4(&inbufptr
[i
])) { /* 4 bytes GB18030 */
887 if (flag
== 0 || flag
!= 5) {
888 encode_string
= get_CT_encode_string("GB18030-1");
891 encode_string_len
= strlen(encode_string
);
893 if (j
+ encode_string_len
+ 4 >= *to_left
)
896 strncpy((char *)outbufptr
+j
, encode_string
, encode_string_len
);
897 j
+= encode_string_len
;
901 if (j
+ 4 >= *to_left
)
904 outbufptr
[j
++] = inbufptr
[i
++];
905 outbufptr
[j
++] = inbufptr
[i
++];
906 outbufptr
[j
++] = inbufptr
[i
++];
907 outbufptr
[j
++] = inbufptr
[i
++];
908 } else if (ISASCII(inbufptr
[i
])) { /* ASCII */
909 if (flag
== 0 || flag
!= 3) {
910 encode_string
= get_CT_encode_string("ASCII");
914 encode_string_len
= strlen(encode_string
);
915 if (j
+ encode_string_len
+ 1 >= *to_left
)
918 strncpy((char *)outbufptr
+j
, encode_string
, encode_string_len
);
919 j
+= encode_string_len
;
923 if (j
+ 1 >= *to_left
)
926 outbufptr
[j
++] = inbufptr
[i
++];
928 i
++; /* Skip this byte */
929 unconv_num
++; /* Count this as an unconverted byte */
933 *from
= (XPointer
)&inbufptr
[i
];
934 *to
= (XPointer
)&outbufptr
[j
];
935 *from_left
= *from_left
- i
;
936 *to_left
= *to_left
- j
;
952 unsigned char inbufptr
[10];
953 unsigned char *outbufptr
= (unsigned char *)*to
;
954 wchar_t *pwc
= (wchar_t *)*from
;
958 int encode_string_len
;
963 while (k
< *from_left
) {
964 if (wctomb((char *)inbufptr
, pwc
[k
++]) == -1)
969 if (isgb(&inbufptr
[i
])) { /* GB2312 */
970 if (flag
== 0 || flag
!= 1) {
971 encode_string
= get_CT_encode_string("GB2312");
975 encode_string_len
= strlen(encode_string
);
976 if (j
+ encode_string_len
+ 2 >= *to_left
)
979 strncpy((char *)outbufptr
+j
, encode_string
, encode_string_len
);
980 j
+= encode_string_len
;
984 if (j
+ 2 >= *to_left
)
987 outbufptr
[j
++] = inbufptr
[i
++];
988 outbufptr
[j
++] = inbufptr
[i
++];
989 } else if (isgb18030_2(&inbufptr
[i
])) {
990 if (flag
== 0 || flag
!= 2) {
991 encode_string
= get_CT_encode_string("GB18030-0");
995 encode_string_len
= strlen(encode_string
);
996 if (j
+ encode_string_len
+ 2 >= *to_left
)
999 strncpy((char *)outbufptr
+j
, encode_string
, encode_string_len
);
1000 j
+= encode_string_len
;
1004 if (j
+ 2 >= *to_left
)
1007 outbufptr
[j
++] = inbufptr
[i
++];
1008 outbufptr
[j
++] = inbufptr
[i
++];
1009 } else if (isgb18030_4(&inbufptr
[i
])) {
1010 if (flag
== 0 || flag
!= 6) {
1011 encode_string
= get_CT_encode_string("GB18030-1");
1012 if (! encode_string
)
1015 encode_string_len
= strlen(encode_string
);
1016 if (j
+ encode_string_len
+ 4 >= *to_left
)
1019 strncpy((char *)outbufptr
+j
, encode_string
, encode_string_len
);
1020 j
+= encode_string_len
;
1024 if (j
+ 4 >= *to_left
)
1027 outbufptr
[j
++] = inbufptr
[i
++];
1028 outbufptr
[j
++] = inbufptr
[i
++];
1029 outbufptr
[j
++] = inbufptr
[i
++];
1030 outbufptr
[j
++] = inbufptr
[i
++];
1031 } else if (ISASCII(inbufptr
[i
])) {
1032 if (flag
== 0 || flag
!= 3) {
1033 encode_string
= get_CT_encode_string("ASCII");
1034 if (! encode_string
)
1037 encode_string_len
= strlen(encode_string
);
1038 if (j
+ encode_string_len
+ 1 >= *to_left
)
1041 strncpy((char *)outbufptr
+j
, encode_string
, encode_string_len
);
1042 j
+= encode_string_len
;
1047 outbufptr
[j
++] = inbufptr
[i
++];
1053 *from
= (XPointer
)&pwc
[k
];
1054 *to
= (XPointer
)&outbufptr
[j
];
1055 *from_left
= *from_left
- k
;
1056 *to_left
= *to_left
- j
;
1071 char *src
= *((char **) from
);
1072 wchar_t *dst
= *((wchar_t **) to
);
1073 int src_left
= *from_left
;
1074 int dst_left
= *to_left
;
1075 int mblen
, unconv_num
= 0;
1077 while (src_left
> 0 && dst_left
> 0) {
1078 mblen
= mbtowc(dst
, src
, src_left
);
1097 *from
= (XPointer
) src
;
1098 *to
= (XPointer
) dst
;
1099 *from_left
= src_left
;
1100 *to_left
= dst_left
;
1114 wchar_t *src
= *((wchar_t **)from
);
1115 char *dst
= *((char **) to
);
1116 char buf
[MB_CUR_MAX
];
1117 int src_left
= *from_left
;
1118 int dst_left
= *to_left
;
1119 int mblen
, unconv_num
= 0;
1121 while (src_left
> 0) {
1122 mblen
= wctomb(buf
, *src
);
1124 if (dst_left
< mblen
) {
1137 for (int i
= 0; i
< mblen
; i
++) {
1142 *from
= (XPointer
) src
;
1143 *to
= (XPointer
) dst
;
1144 *from_left
= src_left
;
1145 *to_left
= dst_left
;
1151 close_converter(XlcConv conv
)
1153 Xfree((char *) conv
);
1159 XlcConvMethods methods
)
1163 conv
= (XlcConv
) Xmalloc(sizeof(XlcConvRec
));
1165 return (XlcConv
) NULL
;
1167 conv
->methods
= methods
;
1168 conv
->state
= (XPointer
) lcd
;
1173 enum { MBSTOCS
, WCSTOCS
, MBTOCS
, CSTOMBS
, CSTOWCS
, MBSTOCTS
, CTSTOMBS
,
1174 CTSTOWCS
, WCSTOCTS
, MBSTOWCS
, WCSTOMBS
, STRTOMBS
};
1176 static XlcConvMethodsRec conv_methods
[] = {
1177 {close_converter
, gb18030_mbstocs
, NULL
},
1178 {close_converter
, gb18030_wcstocs
, NULL
},
1179 {close_converter
, gb18030_mbtocs
, NULL
},
1180 {close_converter
, gb18030_cstombs
, NULL
},
1181 {close_converter
, gb18030_cstowcs
, NULL
},
1182 {close_converter
, gb18030_mbstocts
, NULL
},
1183 {close_converter
, gb18030_ctstombs
, NULL
},
1184 {close_converter
, gb18030_ctstowcs
, NULL
},
1185 {close_converter
, gb18030_wcstocts
, NULL
},
1186 {close_converter
, gb18030_mbstowcs
, NULL
},
1187 {close_converter
, gb18030_wcstombs
, NULL
},
1195 const char *from_type
,
1197 const char *to_type
)
1199 return create_conv(from_lcd
, &conv_methods
[MBSTOCS
]);
1205 const char *from_type
,
1207 const char *to_type
)
1209 return create_conv(from_lcd
, &conv_methods
[WCSTOCS
]);
1215 const char *from_type
,
1217 const char *to_type
)
1219 return create_conv(from_lcd
, &conv_methods
[MBTOCS
]);
1225 const char *from_type
,
1227 const char *to_type
)
1229 return create_conv(from_lcd
, &conv_methods
[CSTOMBS
]);
1235 const char *from_type
,
1237 const char *to_type
)
1239 return create_conv(from_lcd
, &conv_methods
[CSTOWCS
]);
1245 const char *from_type
,
1247 const char *to_type
)
1249 return create_conv(from_lcd
, &conv_methods
[WCSTOCTS
]);
1255 const char *from_type
,
1257 const char *to_type
)
1259 return create_conv(from_lcd
, &conv_methods
[MBSTOCTS
]);
1265 const char *from_type
,
1267 const char *to_type
)
1269 return create_conv(from_lcd
, &conv_methods
[CTSTOMBS
]);
1275 const char *from_type
,
1277 const char *to_type
)
1279 return create_conv(from_lcd
, &conv_methods
[CTSTOWCS
]);
1285 const char *from_type
,
1287 const char *to_type
)
1289 return create_conv(from_lcd
, &conv_methods
[MBSTOWCS
]);
1295 const char *from_type
,
1297 const char *to_type
)
1299 return create_conv(from_lcd
, &conv_methods
[WCSTOMBS
]);
1303 _XlcGb18030Loader(const char *name
)
1307 lcd
= _XlcCreateLC(name
, _XlcGenericMethods
);
1311 if ((_XlcNCompareISOLatin1(XLC_PUBLIC_PART(lcd
)->codeset
, "gb18030", 7))) {
1317 _XlcSetConverter(lcd
, XlcNMultiByte
, lcd
, XlcNCharSet
, open_mbstocs
);
1318 _XlcSetConverter(lcd
, XlcNWideChar
, lcd
, XlcNCharSet
, open_wcstocs
);
1319 _XlcSetConverter(lcd
, XlcNCharSet
, lcd
, XlcNMultiByte
, open_cstombs
);
1320 _XlcSetConverter(lcd
, XlcNCharSet
, lcd
, XlcNWideChar
, open_cstowcs
);
1322 _XlcSetConverter(lcd
, XlcNMultiByte
, lcd
, XlcNChar
, open_mbtocs
);
1325 _XlcSetConverter(lcd
, XlcNMultiByte
, lcd
, XlcNCompoundText
, open_mbstocts
);
1326 _XlcSetConverter(lcd
, XlcNCompoundText
, lcd
, XlcNMultiByte
, open_ctstombs
);
1327 _XlcSetConverter(lcd
, XlcNCompoundText
, lcd
, XlcNWideChar
, open_ctstowcs
);
1328 _XlcSetConverter(lcd
, XlcNWideChar
, lcd
, XlcNCompoundText
, open_wcstocts
);
1331 _XlcSetConverter(lcd
, XlcNMultiByte
, lcd
, XlcNWideChar
, open_mbstowcs
);
1332 _XlcSetConverter(lcd
, XlcNWideChar
, lcd
, XlcNMultiByte
, open_wcstombs
);
1335 _XlcAddUtf8Converters(lcd
);