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 * (c) Copyright 1995 FUJITSU LIMITED 27 * This is source code modified by FUJITSU LIMITED under the Joint 28 * Development Agreement for the CDE/Motif PST. 29 * 30 * Modifier: Masayoshi Shimamura FUJITSU LIMITED 31 * 32 */ 33 /* 34 * 2000 35 * Modifier: Ivan Pascal The XFree86 Project 36 */ 37 38 /* 39 * A generic locale loader for all kinds of ISO-2022 based codesets. 40 * Supports: all locales. 41 * How: Provides generic converters for ISO-2022 based codesets. Extensible as 42 * far as ISO-2022 is extensible: codesets can be given by name in the 43 * stream. Overall distinction between GL (0x00..0x7f) and GR (0x80..0xff). 44 * In every chunk between escape sequences, the number of bytes per 45 * character (char_size) is constant. 46 * Platforms: all systems. 47 */ 48 49 #ifdef HAVE_CONFIG_H 50 #include <config.h> 51 #endif 52 #include "Xlibint.h" 53 #include "XlcGeneric.h" 54 #include <stdio.h> 55 56 #ifndef X_LOCALE 57 #define STDCVT 58 #endif 59 60 typedef struct _CTDataRec { 61 const char *name; 62 const char *encoding; /* Compound Text encoding */ 63 } CTDataRec, *CTData; 64 65 static CTDataRec directionality_data[] = 66 { 67 { "BEGIN_LEFT-TO-RIGHT_TEXT", "\2331]" }, 68 { "BEGIN_RIGHT-TO-LEFT_TEXT", "\2332]" }, 69 { "END_OF_STRING", "\233]" }, 70 }; 71 72 typedef struct _StateRec { 73 XLCd lcd; 74 /* CT state */ 75 XlcCharSet charset; /* charset of current state */ 76 XlcCharSet GL_charset; /* charset of initial state in GL */ 77 XlcCharSet GR_charset; /* charset of initial state in GR */ 78 /* MB shift state */ 79 CodeSet GL_codeset; 80 CodeSet GR_codeset; 81 } StateRec, *State; 82 83 #define GR 0x80 /* begins right-side (non-ascii) region */ 84 #define GL 0x7f /* ends left-side (ascii) region */ 85 #define ESC 0x1b 86 #define CSI 0x9b 87 #define STX 0x02 88 89 #define isrightside(c) ((c) & GR) 90 #define isleftside(c) (!isrightside(c)) 91 92 /* Forward declarations for local routines. */ 93 static int mbstocts (XlcConv conv, XPointer *from, int *from_left, 94 XPointer *to, int *to_left, XPointer *args, int num_args); 95 static int ctstombs (XlcConv conv, XPointer *from, int *from_left, 96 XPointer *to, int *to_left, XPointer *args, int num_args); 97 static int cstombs (XlcConv conv, XPointer *from, int *from_left, 98 XPointer *to, int *to_left, XPointer *args, int num_args); 99 100 /* ------------------------------------------------------------------------- */ 101 /* Misc */ 102 /* ------------------------------------------------------------------------- */ 103 104 static int 105 compare( 106 const char *src, 107 const char *encoding, 108 int length) 109 { 110 const char *start = src; 111 112 while (length-- > 0) { 113 if (*src++ != *encoding++) 114 return 0; 115 if (*encoding == '\0') 116 return src - start; 117 } 118 119 return 0; 120 } 121 122 static unsigned long 123 conv_to_dest( 124 Conversion conv, 125 unsigned long code) 126 { 127 int i; 128 int conv_num = conv->conv_num; 129 FontScope convlist = conv->convlist; 130 131 for (i = 0; i < conv_num; i++) { 132 if (convlist[i].start <= code && code <= convlist[i].end) { 133 switch (convlist[i].shift_direction) { 134 case '+': 135 return(code + convlist[i].shift); 136 case '-': 137 return(code - convlist[i].shift); 138 default: 139 return(code); 140 } 141 } 142 } 143 144 return(code); 145 } 146 147 static unsigned long 148 conv_to_source( 149 Conversion conv, 150 unsigned long code) 151 { 152 int i; 153 int conv_num; 154 FontScope convlist; 155 unsigned long start_p; 156 unsigned long start_m; 157 unsigned long end_p; 158 unsigned long end_m; 159 160 if (!conv) 161 return(code); 162 163 conv_num = conv->conv_num; 164 convlist = conv->convlist; 165 166 for (i = 0; i < conv_num; i++) { 167 switch (convlist[i].shift_direction) { 168 case '+': 169 start_p = convlist[i].start + convlist[i].shift; 170 end_p = convlist[i].end + convlist[i].shift; 171 if (start_p <= code && code <= end_p) 172 return(code - convlist[i].shift); 173 break; 174 case '-': 175 start_m = convlist[i].start - convlist[i].shift; 176 end_m = convlist[i].end - convlist[i].shift; 177 if (start_m <= code && code <= end_m) 178 return(code + convlist[i].shift); 179 break; 180 default: 181 continue; 182 } 183 } 184 185 return(code); 186 } 187 188 static unsigned long 189 mb_to_gi( 190 unsigned long mb, 191 CodeSet codeset) 192 { 193 int i; 194 unsigned long mb_tmp, mask = 0; 195 196 if (codeset->mbconv) { 197 mb_tmp = conv_to_dest(codeset->mbconv, mb); 198 if (mb_tmp != mb) 199 return(mb_tmp); 200 } 201 202 if (codeset->side == XlcC0 || codeset->side == XlcGL || 203 codeset->side == XlcC1 || codeset->side == XlcGR) { 204 205 for (i = 0; i < codeset->length; i++) 206 mask = (mask << 8) | GL; 207 mb = mb & mask; 208 } 209 210 return(mb); 211 } 212 213 static unsigned long 214 gi_to_mb( 215 unsigned long glyph_index, 216 CodeSet codeset) 217 { 218 int i; 219 unsigned long mask = 0; 220 221 if (codeset->side == XlcC1 || codeset->side == XlcGR) { 222 for (i = 0; i < codeset->length; i++) 223 mask = (mask << 8) | GR; 224 glyph_index = glyph_index | mask; 225 } 226 227 if (codeset->mbconv) 228 return( conv_to_source(codeset->mbconv, glyph_index) ); 229 230 return(glyph_index); 231 } 232 233 static Bool 234 gi_to_wc( 235 XLCd lcd, 236 unsigned long glyph_index, 237 CodeSet codeset, 238 wchar_t *wc) 239 { 240 unsigned char mask = 0; 241 unsigned long wc_encoding = codeset->wc_encoding; 242 int length = codeset->length; 243 unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); 244 245 mask = (1 << wc_shift_bits) - 1 ; 246 247 for (*wc = 0, length--; length >= 0; length--) 248 *wc = (*wc << wc_shift_bits) | ((glyph_index >> (length * 8 )) & mask); 249 250 *wc = *wc | wc_encoding; 251 252 return(True); 253 } 254 255 static Bool 256 wc_to_gi( 257 XLCd lcd, 258 wchar_t wc, 259 unsigned long *glyph_index, 260 CodeSet *codeset) 261 { 262 int i; 263 unsigned char mask = 0; 264 unsigned long wc_encoding; 265 unsigned long wc_encode_mask = XLC_GENERIC(lcd, wc_encode_mask); 266 unsigned long wc_shift_bits = XLC_GENERIC(lcd, wc_shift_bits); 267 int codeset_num = XLC_GENERIC(lcd, codeset_num); 268 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 269 270 wc_encoding = wc & wc_encode_mask; 271 for (*codeset = NULL, i = 0; i < codeset_num; i++) { 272 if (wc_encoding == codeset_list[i]->wc_encoding) { 273 *codeset = codeset_list[i]; 274 break; 275 } 276 } 277 if (*codeset == NULL) 278 return(False); 279 280 mask = (1 << wc_shift_bits) - 1 ; 281 282 wc = wc & ~wc_encode_mask; 283 for (*glyph_index = 0, i = (*codeset)->length - 1; i >= 0; i--) 284 *glyph_index = (*glyph_index << 8) | 285 ( ((unsigned long)wc >> (i * wc_shift_bits)) & mask ); 286 287 return(True); 288 } 289 290 static CodeSet 291 mb_parse_codeset( 292 State state, 293 int num, 294 const char **inbufptr, 295 int *from_left) 296 { 297 int len; 298 int from_len = (*from_left) + 1; 299 const char *src = (*inbufptr) - 1; 300 ParseInfo *mb_parse_list = XLC_GENERIC(state->lcd, mb_parse_list); 301 ParseInfo parse_info; 302 CodeSet codeset; 303 304 for (--num ; (parse_info = mb_parse_list[num]) != NULL; num++) { 305 len = compare(src, parse_info->encoding, from_len); 306 if (len > 0) { 307 codeset = parse_info->codeset; 308 if (parse_info->type == E_LSL) 309 state->GL_codeset = codeset; 310 else if (parse_info->type == E_LSR) 311 state->GR_codeset = codeset; 312 --len; 313 *inbufptr += len; 314 *from_left -= len; 315 return codeset; 316 } 317 } 318 return (CodeSet) NULL; 319 } 320 321 static CodeSet 322 byteM_parse_codeset( 323 XLCd lcd, 324 const char *inbufptr, 325 int remaining_bytes) 326 { 327 unsigned char ch; 328 CodeSet codeset; 329 ByteInfoList byteM; 330 ByteInfoListRec byteM_rec; 331 ByteInfo byteinfo; 332 ByteInfoRec byteinfo_rec; 333 Bool hit = False; 334 int i, j, k; 335 336 int codeset_num = XLC_GENERIC(lcd, codeset_num); 337 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 338 339 for (i = 0; i < codeset_num; i++) { 340 codeset = codeset_list[i]; 341 byteM = codeset->byteM; 342 if (codeset->side != XlcNONE || byteM == NULL) 343 continue; 344 if (codeset->length > remaining_bytes) 345 continue; 346 347 for (j = 0; j < codeset->length; j++) { 348 ch = *((const unsigned char *)(inbufptr + j)); 349 byteM_rec = byteM[j]; 350 byteinfo = byteM_rec.byteinfo; 351 352 for (hit = False, k = 0; k < byteM_rec.byteinfo_num; k++) { 353 byteinfo_rec = byteinfo[k]; 354 if (byteinfo_rec.start <= ch && ch <= byteinfo_rec.end) { 355 hit = True; 356 break; 357 } 358 } 359 360 if (!hit) 361 break; 362 } 363 364 if (hit) 365 return(codeset); 366 } 367 368 return(NULL); 369 } 370 371 #define GLGR_parse_codeset(ch) \ 372 (isrightside(ch) ? (state->GR_codeset) : \ 373 (state->GL_codeset) ) 374 375 static XlcCharSet 376 gi_parse_charset( 377 unsigned long glyph_index, 378 CodeSet codeset) 379 { 380 int i; 381 XlcCharSet *charset_list = codeset->charset_list; 382 int num_charsets = codeset->num_charsets; 383 ExtdSegment ctextseg = codeset->ctextseg; 384 XlcCharSet charset = NULL; 385 int area_num; 386 FontScope area; 387 388 /* lockup ct sequence */ 389 for (i = 0; i < num_charsets; i++) { 390 charset = charset_list[i]; 391 if (*charset->ct_sequence != '\0') 392 break; 393 } 394 if (i >= num_charsets) 395 return(NULL); 396 397 if (charset->source != CSsrcStd) 398 return (charset); 399 400 if (!ctextseg) 401 return(charset); 402 403 area = ctextseg->area; 404 area_num = ctextseg->area_num; 405 406 for (i = 0; i < area_num; i++) { 407 408 if (area[i].start <= glyph_index && glyph_index <= area[i].end) { 409 410 charset = ctextseg->charset; 411 412 if (*charset->ct_sequence == '\0') 413 return(NULL); 414 415 break; 416 } 417 } 418 419 return(charset); 420 } 421 422 static Bool 423 ct_parse_csi( 424 const char *inbufptr, 425 int *ctr_seq_len) 426 { 427 int i; 428 int num = sizeof(directionality_data) / sizeof(directionality_data[0]); 429 430 for (i = 0; i < num; i++) { 431 if ( !(*ctr_seq_len = strlen(directionality_data[i].encoding)) ) 432 continue; 433 434 if ( strncmp(inbufptr, directionality_data[i].encoding, 435 *ctr_seq_len) == 0) 436 return(True); 437 } 438 439 return(False); 440 } 441 442 static int 443 cmp_esc_sequence( 444 const char *inbufptr, 445 XlcCharSet charset) 446 { 447 int seq_len, name_len, total_len; 448 unsigned char byte_m, byte_l; 449 const char *ct_sequence = charset->ct_sequence; 450 const char *encoding_name = charset->encoding_name; 451 452 /* check esc sequence */ 453 if ( !(seq_len = strlen(ct_sequence) ) ) 454 return(0); 455 if ( strncmp(inbufptr, ct_sequence, seq_len) != 0) 456 return(0); 457 458 /* Standard Character Set Encoding ? */ 459 if (charset->source == CSsrcStd) 460 return(seq_len); 461 462 /* 463 * Non-Standard Character Set Encoding 464 * 465 * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ 466 * | ctseq | M | L | encoding name | STX | contents | 467 * +--- ---+-----+-----+-----+---- ----+-----+-----+------- ------+ 468 * 4bytes 1byte 1byte variable length 1byte variable length 469 * | | 470 * +----------------------------------------------+ 471 * rest length = ((M - 128) * 128) + (L - 128) 472 */ 473 474 /* get length of encoding name */ 475 inbufptr += seq_len; 476 byte_m = *inbufptr++; 477 byte_l = *inbufptr++; 478 name_len = strlen(encoding_name); 479 480 if (((byte_m - 128) * 128 + (byte_l - 128) - 1) < name_len) 481 return(0); 482 483 if ( _XlcNCompareISOLatin1(inbufptr, encoding_name, name_len) != 0 ) 484 return(0); 485 486 /* check STX (Start of Text) */ 487 inbufptr = inbufptr + name_len; 488 if ( *inbufptr != STX ) 489 return(0); 490 491 total_len = seq_len + name_len + 3; 492 return(total_len); 493 } 494 495 static Bool 496 ct_parse_charset( 497 XLCd lcd, 498 const char *inbufptr, 499 XlcCharSet *charset, 500 int *ctr_seq_len) 501 { 502 int i, j; 503 ExtdSegment ctextseg; 504 int num_charsets; 505 XlcCharSet *charset_list; 506 CodeSet codeset; 507 int codeset_num = XLC_GENERIC(lcd, codeset_num); 508 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 509 int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); 510 SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); 511 512 /* get charset from XLC_XLOCALE by escape sequence */ 513 514 for (i = 0; i < codeset_num; i++) { 515 codeset = codeset_list[i]; 516 517 num_charsets = codeset->num_charsets; 518 charset_list = codeset->charset_list; 519 ctextseg = codeset->ctextseg; 520 521 for (j = 0; j < num_charsets; j++) { 522 *charset = charset_list[j]; 523 if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) 524 return(True); 525 } 526 527 if (ctextseg) { 528 *charset = ctextseg->charset; 529 if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) 530 return(True); 531 } 532 } 533 534 /* get charset from XLC_SEGMENTCONVERSION by escape sequence */ 535 536 if (!segment_conv) 537 return(False); 538 539 for (i = 0; i < segment_conv_num; i++) { 540 *charset = segment_conv[i].source; 541 if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) 542 return(True); 543 *charset = segment_conv[i].dest; 544 if ((*ctr_seq_len = cmp_esc_sequence(inbufptr, *charset))) 545 return(True); 546 } 547 548 return(False); 549 } 550 551 static Bool 552 segment_conversion( 553 XLCd lcd, 554 XlcCharSet *charset, 555 unsigned long *glyph_index) 556 { 557 int i; 558 int segment_conv_num = XLC_GENERIC(lcd, segment_conv_num); 559 SegConv segment_conv = XLC_GENERIC(lcd, segment_conv); 560 FontScopeRec range; 561 ConversionRec conv_rec; 562 563 if (!segment_conv) 564 return(True); 565 566 for (i = 0; i < segment_conv_num; i++) { 567 if (segment_conv[i].source == *charset) 568 break; 569 } 570 571 if (i >= segment_conv_num) 572 return(True); 573 574 range = segment_conv[i].range; 575 if (*glyph_index < range.start || range.end < *glyph_index) 576 return(True); 577 578 *charset = segment_conv[i].dest; 579 conv_rec.conv_num = segment_conv[i].conv_num; 580 conv_rec.convlist = segment_conv[i].conv; 581 *glyph_index = conv_to_dest(&conv_rec, *glyph_index); 582 583 return(True); 584 } 585 586 static CodeSet 587 _XlcGetCodeSetFromName( 588 XLCd lcd, 589 const char *name) 590 { 591 int i, j; 592 XlcCharSet charset; 593 int num_charsets; 594 XlcCharSet *charset_list; 595 CodeSet codeset; 596 597 int codeset_num = XLC_GENERIC(lcd, codeset_num); 598 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 599 600 for (i = 0; i < codeset_num; i++) { 601 codeset = codeset_list[i]; 602 603 num_charsets = codeset->num_charsets; 604 charset_list = codeset->charset_list; 605 606 for (j = 0; j < num_charsets; j++) { 607 charset = charset_list[j]; 608 609 if (!strlen(charset->name)) 610 continue; 611 if ( strcmp(charset->name, name) == 0) 612 return(codeset); 613 } 614 } 615 616 return(NULL); 617 } 618 619 static Bool 620 _XlcGetCodeSetFromCharSet( 621 XLCd lcd, 622 XlcCharSet charset, 623 CodeSet *codeset, 624 unsigned long *glyph_index) 625 { 626 int j, num; 627 CodeSet *codeset_list = XLC_GENERIC(lcd, codeset_list); 628 XlcCharSet *charset_list; 629 int codeset_num, num_charsets; 630 Conversion ctconv; 631 unsigned long glyph_index_tmp = 0; 632 ExtdSegment ctextseg; 633 634 codeset_num = XLC_GENERIC(lcd, codeset_num); 635 636 for (num = 0 ; num < codeset_num; num++) { 637 *codeset = codeset_list[num]; 638 ctconv = (*codeset)->ctconv; 639 ctextseg = (*codeset)->ctextseg; 640 641 num_charsets = (*codeset)->num_charsets; 642 charset_list = (*codeset)->charset_list; 643 644 glyph_index_tmp = conv_to_source(ctconv, *glyph_index); 645 646 if (charset->source == CSsrcStd) { 647 648 /* Standard Character Set Encoding */ 649 if (glyph_index_tmp == *glyph_index) { 650 for (j = 0; j < num_charsets; j++) { 651 if (charset_list[j] == charset) { 652 goto end_loop; 653 } 654 } 655 } 656 657 } else { 658 659 /* Non-Standard Character Set Encoding */ 660 for (j = 0; j < num_charsets; j++) { 661 if (charset_list[j] == charset) { 662 goto end_loop; 663 } 664 } 665 666 if (glyph_index_tmp != *glyph_index) { 667 if (ctextseg && ctextseg->charset == charset) { 668 goto end_loop; 669 } 670 } 671 672 } 673 674 } 675 676 end_loop: 677 if (num < codeset_num) { 678 *glyph_index = glyph_index_tmp; 679 return(True); 680 } 681 682 return(False); 683 } 684 685 #define check_string_encoding(codeset) (codeset->string_encoding) 686 687 static void 688 output_ulong_value( 689 char *outbufptr, 690 unsigned long code, 691 int length, 692 XlcSide side) 693 { 694 int i; 695 696 for (i = (length - 1) * 8; i >= 0; i -= 8) { 697 *outbufptr = ( code >> i) & 0xff; 698 699 if (side == XlcC0 || side == XlcGL) { 700 *outbufptr = *outbufptr & GL; 701 } else if (side == XlcC1 || side == XlcGR) { 702 *outbufptr = *outbufptr | GR; 703 } 704 705 outbufptr++; 706 } 707 } 708 709 /* -------------------------------------------------------------------------- */ 710 /* Init */ 711 /* -------------------------------------------------------------------------- */ 712 713 static XlcCharSet default_GL_charset = 0; 714 static XlcCharSet default_GR_charset = 0; 715 716 static void 717 init_state( 718 XlcConv conv) 719 { 720 State state = (State) conv->state; 721 722 /* for CT */ 723 state->charset = NULL; 724 state->GL_charset = default_GL_charset; 725 state->GR_charset = default_GR_charset; 726 727 /* for MB shift state */ 728 state->GL_codeset = XLC_GENERIC(state->lcd, initial_state_GL); 729 state->GR_codeset = XLC_GENERIC(state->lcd, initial_state_GR); 730 } 731 732 /* -------------------------------------------------------------------------- */ 733 /* Convert */ 734 /* -------------------------------------------------------------------------- */ 735 736 static int 737 mbstowcs_org( 738 XlcConv conv, 739 XPointer *from, 740 int *from_left, 741 XPointer *to, 742 int *to_left, 743 XPointer *args, 744 int num_args) 745 { 746 State state = (State) conv->state; 747 XLCd lcd = state->lcd; 748 749 unsigned char ch; 750 unsigned long mb = 0; 751 wchar_t wc; 752 753 int length = 0, len_left = 0; 754 int unconv_num = 0; 755 int num; 756 757 CodeSet codeset = NULL; 758 759 const char *inbufptr; 760 wchar_t *outbufptr = (wchar_t *) *to; 761 int from_size = *from_left; 762 763 unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); 764 765 if (from == NULL || *from == NULL) { 766 _XlcResetConverter(conv); 767 return( 0 ); 768 } 769 770 inbufptr = *from; 771 772 while (*from_left && *to_left) { 773 774 ch = *inbufptr++; 775 (*from_left)--; 776 777 /* null ? */ 778 if (!ch) { 779 if (outbufptr) {*outbufptr++ = L'\0';} 780 (*to_left)--; 781 782 /* error check */ 783 if (len_left) { 784 unconv_num += (length - len_left); 785 len_left = 0; 786 } 787 788 continue; 789 } 790 791 /* same mb char data */ 792 if (len_left) 793 goto output_one_wc; 794 795 /* next mb char data for single shift ? */ 796 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 797 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 798 if (codeset != NULL) { 799 length = len_left = codeset->length; 800 mb = 0; 801 continue; 802 } 803 } 804 805 /* next mb char data for byteM ? */ 806 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 1))) 807 goto next_mb_char; 808 809 /* next mb char data for GL or GR side ? */ 810 if ((codeset = GLGR_parse_codeset(ch))) 811 goto next_mb_char; 812 813 /* can't find codeset for the ch */ 814 unconv_num++; 815 continue; 816 817 next_mb_char: 818 length = len_left = codeset->length; 819 mb = 0; 820 821 output_one_wc: 822 mb = (mb << 8) | ch; /* 1 byte left shift */ 823 len_left--; 824 825 /* last of one mb char data */ 826 if (!len_left) { 827 gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc); 828 if (outbufptr) {*outbufptr++ = wc;} 829 (*to_left)--; 830 } 831 832 } /* end of while */ 833 834 /* error check on last char */ 835 if (len_left) { 836 inbufptr -= (length - len_left); 837 (*from_left) += (length - len_left); 838 unconv_num += (length - len_left); 839 } 840 841 *from = (XPointer) ((const char *) *from + from_size); 842 *from_left = 0; 843 *to = (XPointer) outbufptr; 844 845 return unconv_num; 846 } 847 848 static int 849 stdc_mbstowcs( 850 XlcConv conv, 851 XPointer *from, 852 int *from_left, 853 XPointer *to, 854 int *to_left, 855 XPointer *args, 856 int num_args) 857 { 858 const char *src = *((const char **) from); 859 wchar_t *dst = *((wchar_t **) to); 860 int src_left = *from_left; 861 int dst_left = *to_left; 862 int length, unconv_num = 0; 863 864 while (src_left > 0 && dst_left > 0) { 865 length = mbtowc(dst, src, src_left); 866 867 if (length > 0) { 868 src += length; 869 src_left -= length; 870 if (dst) 871 dst++; 872 dst_left--; 873 } else if (length < 0) { 874 src++; 875 src_left--; 876 unconv_num++; 877 } else { 878 /* null ? */ 879 src++; 880 src_left--; 881 if (dst) 882 *dst++ = L'\0'; 883 dst_left--; 884 } 885 } 886 887 *from = (XPointer) src; 888 if (dst) 889 *to = (XPointer) dst; 890 *from_left = src_left; 891 *to_left = dst_left; 892 893 return unconv_num; 894 } 895 896 static int 897 wcstombs_org( 898 XlcConv conv, 899 XPointer *from, 900 int *from_left, 901 XPointer *to, 902 int *to_left, 903 XPointer *args, 904 int num_args) 905 { 906 State state = (State) conv->state; 907 XLCd lcd = state->lcd; 908 909 char *encoding; 910 unsigned long mb, glyph_index; 911 wchar_t wc; 912 913 int length; 914 int unconv_num = 0; 915 916 CodeSet codeset; 917 918 const wchar_t *inbufptr = (const wchar_t *) *from; 919 char *outbufptr = *to; 920 int from_size = *from_left; 921 922 const char *default_string = XLC_PUBLIC(lcd, default_string); 923 int defstr_len = strlen(default_string); 924 925 926 while (*from_left && *to_left) { 927 928 wc = *inbufptr++; 929 (*from_left)--; 930 931 /* null ? */ 932 if (!wc) { 933 if (outbufptr) {*outbufptr++ = '\0';} 934 (*to_left)--; 935 936 continue; 937 } 938 939 /* convert */ 940 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 941 942 /* output default_string of XDefaultString() */ 943 if (*to_left < defstr_len) 944 break; 945 if (outbufptr) { 946 memcpy(outbufptr, default_string, defstr_len); 947 outbufptr += defstr_len; 948 } 949 (*to_left) -= defstr_len; 950 951 unconv_num++; 952 953 } else { 954 mb = gi_to_mb(glyph_index, codeset); 955 if (codeset->parse_info) { 956 Bool need_shift = False; 957 switch (codeset->parse_info->type) { 958 case E_LSL : 959 if (codeset != state->GL_codeset) { 960 need_shift = True; 961 state->GL_codeset = codeset; 962 } 963 break; 964 case E_LSR : 965 if (codeset != state->GR_codeset) { 966 need_shift = True; 967 state->GR_codeset = codeset; 968 } 969 break; 970 /* case E_SS */ 971 default: 972 need_shift = True; 973 } 974 975 /* output shift sequence */ 976 if (need_shift) { 977 encoding = codeset->parse_info->encoding; 978 length = strlen(encoding); 979 if (*to_left < length) 980 break; 981 if (outbufptr) { 982 memcpy(outbufptr, encoding, length); 983 outbufptr += length; 984 } 985 (*to_left) -= length; 986 } 987 } 988 989 /* output characters */ 990 length = codeset->length; 991 if (*to_left < length) 992 break; 993 994 if (outbufptr) { 995 output_ulong_value(outbufptr, mb, length, XlcNONE); 996 outbufptr += length; 997 } 998 999 (*to_left) -= length; 1000 } 1001 1002 } /* end of while */ 1003 1004 *from = (XPointer) ((const wchar_t *) *from + from_size); 1005 *from_left = 0; 1006 *to = (XPointer) outbufptr; 1007 1008 return unconv_num; 1009 } 1010 1011 static int 1012 stdc_wcstombs( 1013 XlcConv conv, 1014 XPointer *from, 1015 int *from_left, 1016 XPointer *to, 1017 int *to_left, 1018 XPointer *args, 1019 int num_args) 1020 { 1021 const wchar_t *src = *((const wchar_t **) from); 1022 char *dst = *((char **) to); 1023 int src_left = *from_left; 1024 int dst_left = *to_left; 1025 int length, unconv_num = 0; 1026 1027 while (src_left > 0 && dst_left >= MB_CUR_MAX) { 1028 length = wctomb(dst, *src); /* XXX */ 1029 1030 if (length > 0) { 1031 src++; 1032 src_left--; 1033 if (dst) 1034 dst += length; 1035 dst_left -= length; 1036 } else if (length < 0) { 1037 src++; 1038 src_left--; 1039 unconv_num++; 1040 } 1041 } 1042 1043 *from = (XPointer) src; 1044 if (dst) 1045 *to = (XPointer) dst; 1046 *from_left = src_left; 1047 *to_left = dst_left; 1048 1049 return unconv_num; 1050 } 1051 1052 static int 1053 wcstocts( 1054 XlcConv conv, 1055 XPointer *from, 1056 int *from_left, 1057 XPointer *to, 1058 int *to_left, 1059 XPointer *args, 1060 int num_args) 1061 { 1062 State state = (State) conv->state; 1063 XLCd lcd = state->lcd; 1064 1065 unsigned long glyph_index; 1066 wchar_t wc; 1067 1068 int total_len, seq_len, name_len; 1069 int unconv_num = 0; 1070 Bool first_flag = True, standard_flag; 1071 XlcSide side; 1072 1073 CodeSet codeset; 1074 XlcCharSet charset, old_charset = NULL; 1075 const char *ct_sequence; 1076 1077 const wchar_t *inbufptr = (const wchar_t *) *from; 1078 char *outbufptr = *to; 1079 int from_size = *from_left; 1080 char *ext_seg_len = NULL; 1081 1082 while (*from_left && *to_left) { 1083 1084 wc = *inbufptr++; 1085 (*from_left)--; 1086 1087 /* null ? */ 1088 if (!wc) { 1089 if (outbufptr) {*outbufptr++ = '\0';} 1090 (*to_left)--; 1091 1092 continue; 1093 } 1094 1095 /* convert */ 1096 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 1097 unconv_num++; 1098 continue; 1099 } 1100 1101 /* parse charset */ 1102 if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { 1103 unconv_num++; 1104 continue; 1105 } 1106 1107 /* Standard Character Set Encoding ? */ 1108 standard_flag = charset->source == CSsrcStd ? True : False; 1109 1110 /* 1111 * Non-Standard Character Set Encoding 1112 * 1113 * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ 1114 * | esc sequence | M | L | encoding name | STX | 1115 * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ 1116 * 4bytes 1byte 1byte variable length 1byte 1117 * | | 1118 * +-----------------------------------------+ 1119 * name length = ((M - 128) * 128) + (L - 128) 1120 */ 1121 1122 /* make encoding data */ 1123 ct_sequence = charset->ct_sequence; 1124 side = charset->side; 1125 seq_len = strlen(ct_sequence); 1126 if (standard_flag) { 1127 name_len = 0; 1128 total_len = seq_len; 1129 } else { 1130 name_len = strlen(charset->encoding_name) + 1; 1131 total_len = seq_len + name_len + 2; 1132 } 1133 1134 /* output escape sequence of CT */ 1135 if ( (charset != old_charset) && 1136 !(first_flag && charset->string_encoding) ){ 1137 1138 if ( (ext_seg_len != NULL) && outbufptr) { 1139 int i = (outbufptr - ext_seg_len) - 2; 1140 *ext_seg_len++ = i / 128 + 128; 1141 *ext_seg_len = i % 128 + 128; 1142 ext_seg_len = NULL; 1143 } 1144 1145 if (*to_left < total_len + 1) { 1146 unconv_num++; 1147 break; 1148 } 1149 1150 if (outbufptr) { 1151 strcpy((char *)outbufptr, ct_sequence); 1152 outbufptr += seq_len; 1153 1154 if (!standard_flag) { 1155 const char *i = charset->encoding_name; 1156 ext_seg_len = outbufptr; 1157 outbufptr += 2; 1158 for (; *i ; i++) 1159 *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ? 1160 *i - 'A' + 'a' : *i; 1161 *outbufptr++ = STX; 1162 } 1163 } 1164 1165 (*to_left) -= total_len; 1166 1167 first_flag = False; 1168 old_charset = charset; 1169 } 1170 1171 /* output glyph index */ 1172 if (codeset->ctconv) 1173 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 1174 if (*to_left < charset->char_size) { 1175 unconv_num++; 1176 break; 1177 } 1178 1179 if (outbufptr) { 1180 output_ulong_value(outbufptr, glyph_index, charset->char_size, side); 1181 outbufptr += charset->char_size; 1182 } 1183 1184 (*to_left) -= charset->char_size; 1185 1186 } /* end of while */ 1187 1188 if ( (ext_seg_len != NULL) && outbufptr) { 1189 int i = (outbufptr - ext_seg_len) - 2; 1190 *ext_seg_len++ = i / 128 + 128; 1191 *ext_seg_len = i % 128 + 128; 1192 } 1193 1194 *from = (XPointer) ((const wchar_t *) *from + from_size); 1195 *from_left = 0; 1196 *to = (XPointer) outbufptr; 1197 1198 return unconv_num; 1199 } 1200 1201 static int 1202 stdc_wcstocts( 1203 XlcConv conv, 1204 XPointer *from, 1205 int *from_left, 1206 XPointer *to, 1207 int *to_left, 1208 XPointer *args, 1209 int num_args) 1210 { 1211 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1212 char *buf_ptr1 = buf; 1213 int buf_left1 = (*from_left) * MB_CUR_MAX; 1214 char *buf_ptr2 = buf_ptr1; 1215 int buf_left2; 1216 int unconv_num1 = 0, unconv_num2 = 0; 1217 1218 unconv_num1 = stdc_wcstombs(conv, 1219 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1220 if (unconv_num1 < 0) 1221 goto ret; 1222 1223 buf_left2 = buf_ptr1 - buf_ptr2; 1224 1225 unconv_num2 = mbstocts(conv, 1226 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1227 if (unconv_num2 < 0) 1228 goto ret; 1229 1230 ret: 1231 Xfree(buf); 1232 1233 return (unconv_num1 + unconv_num2); 1234 } 1235 1236 static int 1237 ctstowcs( 1238 XlcConv conv, 1239 XPointer *from, 1240 int *from_left, 1241 XPointer *to, 1242 int *to_left, 1243 XPointer *args, 1244 int num_args) 1245 { 1246 State state = (State) conv->state; 1247 XLCd lcd = state->lcd; 1248 1249 unsigned char ch; 1250 unsigned long glyph_index = 0; 1251 wchar_t wc; 1252 1253 int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0; 1254 int unconv_num = 0; 1255 1256 CodeSet codeset = NULL; 1257 XlcCharSet charset_tmp; 1258 1259 const char *inbufptr; 1260 wchar_t *outbufptr = (wchar_t *) *to; 1261 int from_size = *from_left; 1262 1263 _XlcResetConverter(conv); /* ??? */ 1264 1265 if (from == NULL || *from == NULL) { 1266 _XlcResetConverter(conv); 1267 return( 0 ); 1268 } 1269 inbufptr = *from; 1270 1271 while (*from_left && *to_left) { 1272 1273 ch = *inbufptr++; 1274 (*from_left)--; 1275 1276 /* null ? */ 1277 if (!ch) { 1278 if (outbufptr) {*outbufptr++ = L'\0';} 1279 (*to_left)--; 1280 1281 /* error check */ 1282 if (gi_len_left) { 1283 unconv_num += (gi_len - gi_len_left); 1284 gi_len_left = 0; 1285 } 1286 1287 continue; 1288 } 1289 1290 /* same glyph_index data */ 1291 if (gi_len_left) 1292 goto output_one_wc; 1293 1294 /* control sequence ? */ 1295 if (ch == CSI) { 1296 if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) ) 1297 goto skip_the_seg; 1298 1299 if (*from_left + 1 < ctr_seq_len) { 1300 inbufptr--; 1301 (*from_left)++; 1302 unconv_num += *from_left; 1303 break; 1304 } 1305 1306 /* skip the control sequence */ 1307 inbufptr += (ctr_seq_len - 1); 1308 *from_left -= (ctr_seq_len - 1); 1309 1310 continue; 1311 } 1312 1313 /* escape sequence ? */ 1314 if (ch == ESC) { 1315 if ( !ct_parse_charset(lcd, 1316 inbufptr - 1, &state->charset, &ctr_seq_len) ) 1317 goto skip_the_seg; 1318 1319 if (state->charset->side == XlcC0 || 1320 state->charset->side == XlcGL) 1321 { 1322 state->GL_charset = state->charset; 1323 } 1324 else if (state->charset->side == XlcC1 || 1325 state->charset->side == XlcGR) 1326 { 1327 state->GR_charset = state->charset; 1328 } 1329 else if (state->charset->side == XlcGLGR) 1330 { 1331 state->GL_charset = state->charset; 1332 state->GR_charset = state->charset; 1333 } 1334 1335 if (*from_left + 1 < ctr_seq_len) { 1336 inbufptr--; 1337 (*from_left)++; 1338 unconv_num += *from_left; 1339 break; 1340 } 1341 1342 /* skip the escape sequence */ 1343 inbufptr += (ctr_seq_len - 1); 1344 *from_left -= (ctr_seq_len - 1); 1345 1346 continue; 1347 } 1348 1349 /* check current state */ 1350 if (isleftside(ch)) 1351 state->charset = state->GL_charset; 1352 else 1353 state->charset = state->GR_charset; 1354 1355 gi_len = gi_len_left = state->charset->char_size; 1356 glyph_index = 0; 1357 1358 output_one_wc: 1359 if (state->charset->side == XlcC1 || state->charset->side == XlcGR) 1360 glyph_index = (glyph_index << 8) | (ch & GL); 1361 else 1362 glyph_index = (glyph_index << 8) | ch; 1363 1364 gi_len_left--; 1365 1366 /* last of one glyph_index data */ 1367 if (!gi_len_left) { 1368 1369 /* segment conversion */ 1370 charset_tmp = state->charset; 1371 segment_conversion(lcd, &charset_tmp, &glyph_index); 1372 1373 /* get codeset */ 1374 if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, 1375 &codeset, &glyph_index) ) { 1376 unconv_num += gi_len; 1377 continue; 1378 } 1379 1380 /* convert glyph index to wicd char */ 1381 gi_to_wc(lcd, glyph_index, codeset, &wc); 1382 if (outbufptr) {*outbufptr++ = wc;} 1383 (*to_left)--; 1384 } 1385 1386 continue; 1387 1388 skip_the_seg: 1389 /* skip until next escape or control sequence */ 1390 while ( *from_left ) { 1391 ch = *inbufptr++; 1392 (*from_left)--; 1393 unconv_num++; 1394 1395 if (ch == ESC || ch == CSI) { 1396 inbufptr--; 1397 (*from_left)++; 1398 unconv_num--; 1399 break; 1400 } 1401 } 1402 1403 if ( !(*from_left) ) 1404 break; 1405 1406 } /* end of while */ 1407 1408 /* error check on last char */ 1409 if (gi_len_left) { 1410 inbufptr -= (gi_len - gi_len_left); 1411 (*from_left) += (gi_len - gi_len_left); 1412 unconv_num += (gi_len - gi_len_left); 1413 } 1414 1415 *from = (XPointer) ((const char *) *from + from_size); 1416 *from_left = 0; 1417 *to = (XPointer) outbufptr; 1418 1419 return unconv_num; 1420 } 1421 1422 static int 1423 cstowcs( 1424 XlcConv conv, 1425 XPointer *from, 1426 int *from_left, 1427 XPointer *to, 1428 int *to_left, 1429 XPointer *args, 1430 int num_args) 1431 { 1432 State state = (State) conv->state; 1433 XLCd lcd = state->lcd; 1434 1435 unsigned char ch; 1436 unsigned long glyph_index = 0; 1437 wchar_t wc; 1438 int gi_len_left = 0, gi_len = 0; 1439 1440 int unconv_num = 0; 1441 1442 CodeSet codeset = NULL; 1443 XlcCharSet charset, charset_tmp; 1444 1445 const char *inbufptr; 1446 wchar_t *outbufptr = (wchar_t *) *to; 1447 int from_size = *from_left; 1448 1449 if (from == NULL || *from == NULL) { 1450 return( 0 ); 1451 } 1452 1453 inbufptr = *from; 1454 1455 charset = (XlcCharSet) args[0]; 1456 1457 while (*from_left && *to_left) { 1458 1459 if (!gi_len_left) { 1460 gi_len_left = gi_len = charset->char_size; 1461 glyph_index = 0; 1462 } 1463 1464 ch = *inbufptr++; 1465 (*from_left)--; 1466 1467 /* null ? */ 1468 if (!ch) { 1469 if (outbufptr) {*outbufptr++ = L'\0';} 1470 (*to_left)--; 1471 1472 /* error check */ 1473 if (gi_len_left) { 1474 unconv_num += (gi_len - gi_len_left); 1475 gi_len_left = 0; 1476 } 1477 continue; 1478 } 1479 1480 if (charset->side == XlcC1 || charset->side == XlcGR) 1481 glyph_index = (glyph_index << 8) | (ch & GL); 1482 else 1483 glyph_index = (glyph_index << 8) | ch; 1484 1485 gi_len_left--; 1486 1487 /* last of one glyph_index data */ 1488 if (!gi_len_left) { 1489 1490 /* segment conversion */ 1491 charset_tmp = charset; 1492 segment_conversion(lcd, &charset_tmp, &glyph_index); 1493 1494 /* get codeset */ 1495 if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, 1496 &codeset, &glyph_index) ) { 1497 unconv_num += gi_len; 1498 continue; 1499 } 1500 1501 /* convert glyph index to wicd char */ 1502 gi_to_wc(lcd, glyph_index, codeset, &wc); 1503 if (outbufptr) {*outbufptr++ = wc;} 1504 (*to_left)--; 1505 } 1506 1507 } /* end of while */ 1508 1509 /* error check on last char */ 1510 if (gi_len_left) { 1511 inbufptr -= (gi_len - gi_len_left); 1512 (*from_left) += (gi_len - gi_len_left); 1513 unconv_num += (gi_len - gi_len_left); 1514 } 1515 1516 *from = (XPointer) ((const char *) *from + from_size); 1517 *from_left = 0; 1518 *to = (XPointer) outbufptr; 1519 1520 return unconv_num; 1521 } 1522 1523 static int 1524 stdc_ctstowcs( 1525 XlcConv conv, 1526 XPointer *from, 1527 int *from_left, 1528 XPointer *to, 1529 int *to_left, 1530 XPointer *args, 1531 int num_args) 1532 { 1533 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1534 char *buf_ptr1 = buf; 1535 int buf_left1 = (*from_left) * MB_CUR_MAX; 1536 char *buf_ptr2 = buf_ptr1; 1537 int buf_left2; 1538 int unconv_num1 = 0, unconv_num2 = 0; 1539 1540 unconv_num1 = ctstombs(conv, 1541 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1542 if (unconv_num1 < 0) 1543 goto ret; 1544 1545 buf_left2 = buf_ptr1 - buf_ptr2; 1546 1547 unconv_num2 = stdc_mbstowcs(conv, 1548 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1549 if (unconv_num2 < 0) 1550 goto ret; 1551 1552 ret: 1553 Xfree(buf); 1554 1555 return (unconv_num1 + unconv_num2); 1556 } 1557 1558 static int 1559 stdc_cstowcs( 1560 XlcConv conv, 1561 XPointer *from, 1562 int *from_left, 1563 XPointer *to, 1564 int *to_left, 1565 XPointer *args, 1566 int num_args) 1567 { 1568 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1569 char *buf_ptr1 = buf; 1570 int buf_left1 = (*from_left) * MB_CUR_MAX; 1571 char *buf_ptr2 = buf_ptr1; 1572 int buf_left2; 1573 int unconv_num1 = 0, unconv_num2 = 0; 1574 1575 unconv_num1 = cstombs(conv, 1576 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1577 if (unconv_num1 < 0) 1578 goto ret; 1579 1580 buf_left2 = buf_ptr1 - buf_ptr2; 1581 1582 unconv_num2 = stdc_mbstowcs(conv, 1583 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1584 if (unconv_num2 < 0) 1585 goto ret; 1586 1587 ret: 1588 Xfree(buf); 1589 1590 return (unconv_num1 + unconv_num2); 1591 } 1592 1593 static int 1594 mbstocts( 1595 XlcConv conv, 1596 XPointer *from, 1597 int *from_left, 1598 XPointer *to, 1599 int *to_left, 1600 XPointer *args, 1601 int num_args) 1602 { 1603 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 1604 char *buf_ptr1 = buf; 1605 int buf_left1 = (*from_left); 1606 char *buf_ptr2 = buf_ptr1; 1607 int buf_left2; 1608 int unconv_num1 = 0, unconv_num2 = 0; 1609 1610 unconv_num1 = mbstowcs_org(conv, 1611 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1612 if (unconv_num1 < 0) 1613 goto ret; 1614 1615 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 1616 1617 unconv_num2 += wcstocts(conv, 1618 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1619 if (unconv_num2 < 0) 1620 goto ret; 1621 1622 ret: 1623 Xfree(buf); 1624 1625 return (unconv_num1 + unconv_num2); 1626 } 1627 1628 static int 1629 mbstostr( 1630 XlcConv conv, 1631 XPointer *from, 1632 int *from_left, 1633 XPointer *to, 1634 int *to_left, 1635 XPointer *args, 1636 int num_args) 1637 { 1638 State state = (State) conv->state; 1639 XLCd lcd = state->lcd; 1640 1641 unsigned char ch; 1642 unsigned long mb = 0; 1643 1644 int length = 0, len_left = 0; 1645 int unconv_num = 0; 1646 int num; 1647 1648 CodeSet codeset = NULL; 1649 1650 const char *inbufptr; 1651 char *outbufptr = *to; 1652 int from_size = *from_left; 1653 1654 unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); 1655 1656 if (from == NULL || *from == NULL) { 1657 _XlcResetConverter(conv); 1658 return( 0 ); 1659 } 1660 1661 inbufptr = *from; 1662 1663 while (*from_left && *to_left) { 1664 1665 ch = *inbufptr++; 1666 (*from_left)--; 1667 1668 /* null ? */ 1669 if (!ch) { 1670 if (outbufptr) {*outbufptr++ = '\0';} 1671 (*to_left)--; 1672 1673 /* error check */ 1674 if (len_left) { 1675 unconv_num += (length - len_left); 1676 len_left = 0; 1677 } 1678 1679 continue; 1680 } 1681 1682 /* same mb char data */ 1683 if (len_left) 1684 goto output_one_mb; 1685 1686 /* next mb char data for single shift ? */ 1687 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 1688 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 1689 if (codeset != NULL) { 1690 length = len_left = codeset->length; 1691 mb = 0; 1692 continue; 1693 } 1694 } 1695 1696 /* next char data : byteM ? */ 1697 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 1))) 1698 goto next_mb_char; 1699 1700 /* next char data : GL or GR side ? */ 1701 if ((codeset = GLGR_parse_codeset(ch))) 1702 goto next_mb_char; 1703 1704 /* can't find codeset for the ch */ 1705 unconv_num++; 1706 continue; 1707 1708 next_mb_char: 1709 length = len_left = codeset->length; 1710 mb = 0; 1711 1712 output_one_mb: 1713 mb = (mb << 8) | ch; /* 1 byte left shift */ 1714 len_left--; 1715 1716 /* last of one mb char data */ 1717 if (!len_left) { 1718 if (check_string_encoding(codeset)) { 1719 if (outbufptr) {*outbufptr++ = mb & 0xff;} 1720 (*to_left)--; 1721 } else { 1722 unconv_num++; 1723 } 1724 } 1725 1726 } /* end of while */ 1727 1728 /* error check on last char */ 1729 if (len_left) { 1730 inbufptr -= (length - len_left); 1731 (*from_left) += (length - len_left); 1732 unconv_num += (length - len_left); 1733 } 1734 1735 *from = (XPointer) ((const char *) *from + from_size); 1736 *from_left = 0; 1737 *to = (XPointer) outbufptr; 1738 1739 return unconv_num; 1740 } 1741 1742 static int 1743 mbtocs( 1744 XlcConv conv, 1745 XPointer *from, 1746 int *from_left, 1747 XPointer *to, 1748 int *to_left, 1749 XPointer *args, 1750 int num_args) 1751 { 1752 State state = (State) conv->state; 1753 XLCd lcd = state->lcd; 1754 1755 unsigned char ch; 1756 unsigned long mb = 0; 1757 unsigned long glyph_index; 1758 1759 int length = 0, len_left = 0, char_len; 1760 int unconv_num = 0; 1761 int num; 1762 XlcSide side; 1763 1764 CodeSet codeset = NULL; 1765 XlcCharSet charset = NULL; 1766 1767 const char *inbufptr; 1768 char *outbufptr = *to; 1769 int from_size = *from_left; 1770 1771 unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); 1772 1773 if (from == NULL || *from == NULL) { 1774 _XlcResetConverter(conv); 1775 return( 0 ); 1776 } 1777 1778 inbufptr = *from; 1779 1780 while (*from_left && *to_left) { 1781 1782 ch = *inbufptr++; 1783 (*from_left)--; 1784 1785 /* null ? */ 1786 if (!ch) { 1787 unconv_num = 1; 1788 if (len_left) 1789 unconv_num += (length - len_left); 1790 break; 1791 } 1792 1793 /* same mb char data */ 1794 if (len_left) 1795 goto output; 1796 1797 /* next mb char data for single shift ? */ 1798 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 1799 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 1800 if (codeset != NULL) { 1801 length = len_left = codeset->length; 1802 mb = 0; 1803 continue; 1804 } 1805 } 1806 1807 /* next mb char data for byteM ? */ 1808 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1), (*from_left) + 1))) 1809 goto next_mb_char; 1810 1811 /* next mb char data for GL or GR side ? */ 1812 if ((codeset = GLGR_parse_codeset(ch))) 1813 goto next_mb_char; 1814 1815 /* can't find codeset for the ch */ 1816 unconv_num = 1; 1817 break; 1818 1819 next_mb_char: 1820 length = len_left = codeset->length; 1821 mb = 0; 1822 1823 output: 1824 mb = (mb << 8) | ch; /* 1 byte left shift */ 1825 len_left--; 1826 1827 /* last of one mb char data */ 1828 if (!len_left) { 1829 glyph_index = mb_to_gi(mb, codeset); 1830 if (!(charset = gi_parse_charset(glyph_index, codeset))) { 1831 unconv_num = length; 1832 break; 1833 } 1834 char_len = charset->char_size; 1835 side = charset->side; 1836 1837 /* output glyph index */ 1838 if (codeset->ctconv) 1839 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 1840 if (*to_left < char_len) { 1841 unconv_num = length; 1842 break; 1843 } 1844 1845 if (outbufptr) { 1846 output_ulong_value(outbufptr, glyph_index, char_len, side); 1847 outbufptr += char_len; 1848 } 1849 1850 (*to_left) -= char_len; 1851 1852 break; 1853 } 1854 1855 } /* end of while */ 1856 1857 /* error end */ 1858 if (unconv_num) { 1859 *from = (XPointer) ((const char *) *from + from_size); 1860 *from_left = 0; 1861 *to = (XPointer) outbufptr; 1862 return -1; 1863 } 1864 1865 /* normal end */ 1866 *from = (XPointer) inbufptr; 1867 *to = (XPointer) outbufptr; 1868 1869 if (num_args > 0) 1870 *((XlcCharSet *) args[0]) = charset; 1871 1872 return 0; 1873 } 1874 1875 static int 1876 mbstocs( 1877 XlcConv conv, 1878 XPointer *from, 1879 int *from_left, 1880 XPointer *to, 1881 int *to_left, 1882 XPointer *args, 1883 int num_args) 1884 { 1885 int ret; 1886 XlcCharSet charset_old, charset = NULL; 1887 XPointer tmp_args[1]; 1888 1889 const char *inbufptr; 1890 int in_left; 1891 char *outbufptr; 1892 int out_left; 1893 tmp_args[0] = (XPointer) &charset; 1894 1895 ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); 1896 charset_old = charset; 1897 1898 while ( ret == 0 && *from_left && *to_left) { 1899 inbufptr = *from; 1900 in_left = *from_left; 1901 outbufptr = *to; 1902 out_left = *to_left; 1903 ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); 1904 if (charset_old != charset) { 1905 *from = (XPointer) inbufptr; 1906 *from_left = in_left; 1907 *to = (XPointer) outbufptr; 1908 *to_left = out_left; 1909 break; 1910 } 1911 } 1912 1913 if (num_args > 0) 1914 *((XlcCharSet *) args[0]) = charset_old; 1915 1916 /* error end */ 1917 if (ret != 0) 1918 return( -1 ); 1919 1920 return(0); 1921 } 1922 1923 static int 1924 wcstostr( 1925 XlcConv conv, 1926 XPointer *from, 1927 int *from_left, 1928 XPointer *to, 1929 int *to_left, 1930 XPointer *args, 1931 int num_args) 1932 { 1933 State state = (State) conv->state; 1934 XLCd lcd = state->lcd; 1935 1936 char *encoding; 1937 unsigned long mb, glyph_index; 1938 wchar_t wc; 1939 1940 int length; 1941 int unconv_num = 0; 1942 1943 CodeSet codeset; 1944 1945 const wchar_t *inbufptr = (const wchar_t *) *from; 1946 char *outbufptr = *to; 1947 int from_size = *from_left; 1948 1949 const char *default_string = XLC_PUBLIC(lcd, default_string); 1950 int defstr_len = strlen(default_string); 1951 1952 while (*from_left && *to_left) { 1953 1954 wc = *inbufptr++; 1955 (*from_left)--; 1956 1957 /* null ? */ 1958 if (!wc) { 1959 if (outbufptr) {*outbufptr++ = '\0';} 1960 (*to_left)--; 1961 1962 continue; 1963 } 1964 1965 /* convert */ 1966 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 1967 1968 /* output default_string of XDefaultString() */ 1969 if (*to_left < defstr_len) 1970 break; 1971 if (outbufptr) { 1972 memcpy(outbufptr, default_string, defstr_len); 1973 outbufptr += defstr_len; 1974 } 1975 (*to_left) -= defstr_len; 1976 1977 unconv_num++; 1978 1979 } else { 1980 mb = gi_to_mb(glyph_index, codeset); 1981 1982 if (check_string_encoding(codeset)) { 1983 if (codeset->parse_info) { 1984 Bool need_shift = False; 1985 switch (codeset->parse_info->type) { 1986 case E_LSL : 1987 if (codeset != state->GL_codeset) { 1988 need_shift = True; 1989 state->GL_codeset = codeset; 1990 } 1991 break; 1992 case E_LSR : 1993 if (codeset != state->GR_codeset) { 1994 need_shift = True; 1995 state->GR_codeset = codeset; 1996 } 1997 break; 1998 /* case E_SS */ 1999 default: 2000 need_shift = True; 2001 } 2002 2003 /* output shift sequence */ 2004 if (need_shift) { 2005 encoding = codeset->parse_info->encoding; 2006 length = strlen(encoding); 2007 if (*to_left < length) 2008 break; 2009 2010 if (outbufptr) { 2011 memcpy(outbufptr, encoding, length); 2012 outbufptr += length; 2013 } 2014 (*to_left) -= length; 2015 } 2016 } 2017 2018 /* output characters */ 2019 length = codeset->length; 2020 if (*to_left < length) 2021 break; 2022 2023 if (outbufptr) { 2024 output_ulong_value(outbufptr, mb, length, XlcNONE); 2025 outbufptr += length; 2026 } 2027 2028 (*to_left) -= length; 2029 } else { 2030 unconv_num++; 2031 } 2032 } 2033 2034 } /* end of while */ 2035 2036 *from = (XPointer) ((const wchar_t *) *from + from_size); 2037 *from_left = 0; 2038 *to = (XPointer) outbufptr; 2039 2040 return unconv_num; 2041 } 2042 2043 static int 2044 stdc_wcstostr( 2045 XlcConv conv, 2046 XPointer *from, 2047 int *from_left, 2048 XPointer *to, 2049 int *to_left, 2050 XPointer *args, 2051 int num_args) 2052 { 2053 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 2054 char *buf_ptr1 = buf; 2055 int buf_left1 = (*from_left) * MB_CUR_MAX; 2056 char *buf_ptr2 = buf_ptr1; 2057 int buf_left2; 2058 int unconv_num1 = 0, unconv_num2 = 0; 2059 2060 unconv_num1 = stdc_wcstombs(conv, 2061 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2062 if (unconv_num1 < 0) 2063 goto ret; 2064 2065 buf_left2 = buf_ptr1 - buf_ptr2; 2066 2067 unconv_num2 = mbstostr(conv, 2068 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2069 if (unconv_num2 < 0) 2070 goto ret; 2071 2072 ret: 2073 Xfree(buf); 2074 2075 return (unconv_num1 + unconv_num2); 2076 } 2077 2078 static int 2079 wctocs( 2080 XlcConv conv, 2081 XPointer *from, 2082 int *from_left, 2083 XPointer *to, 2084 int *to_left, 2085 XPointer *args, 2086 int num_args) 2087 { 2088 State state = (State) conv->state; 2089 XLCd lcd = state->lcd; 2090 2091 wchar_t wc; 2092 unsigned long glyph_index; 2093 2094 int char_len; 2095 int unconv_num = 0; 2096 XlcSide side; 2097 2098 CodeSet codeset; 2099 XlcCharSet charset = NULL; 2100 2101 const wchar_t *inbufptr = (const wchar_t *) *from; 2102 char *outbufptr = *to; 2103 int from_size = *from_left; 2104 2105 if (*from_left && *to_left) { 2106 2107 wc = *inbufptr++; 2108 (*from_left)--; 2109 2110 /* null ? */ 2111 if (!wc) { 2112 unconv_num = 1; 2113 goto end; 2114 } 2115 2116 /* convert */ 2117 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 2118 unconv_num = 1; 2119 goto end; 2120 } 2121 2122 if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { 2123 unconv_num = 1; 2124 goto end; 2125 } 2126 char_len = charset->char_size; 2127 side = charset->side; 2128 2129 /* output glyph index */ 2130 if (codeset->ctconv) 2131 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 2132 if (*to_left < char_len) { 2133 unconv_num++; 2134 goto end; 2135 } 2136 2137 if (outbufptr) { 2138 output_ulong_value(outbufptr, glyph_index, char_len, side); 2139 outbufptr += char_len; 2140 } 2141 2142 (*to_left) -= char_len; 2143 2144 } 2145 2146 end: 2147 2148 /* error end */ 2149 if (unconv_num) { 2150 *from = (XPointer) ((const wchar_t *) *from + from_size); 2151 *from_left = 0; 2152 *to = (XPointer) outbufptr; 2153 return -1; 2154 } 2155 2156 /* normal end */ 2157 *from = (XPointer) inbufptr; 2158 *to = (XPointer) outbufptr; 2159 2160 if (num_args > 0) 2161 *((XlcCharSet *) args[0]) = charset; 2162 2163 return 0; 2164 } 2165 2166 static int 2167 stdc_wctocs( 2168 XlcConv conv, 2169 XPointer *from, 2170 int *from_left, 2171 XPointer *to, 2172 int *to_left, 2173 XPointer *args, 2174 int num_args) 2175 { 2176 const wchar_t *src = *((const wchar_t **) from); 2177 wchar_t wch; 2178 XPointer tmp_from, save_from = *from; 2179 char tmp[32]; 2180 int length, ret, src_left = *from_left; 2181 int from_size = *from_left; 2182 2183 if (src_left > 0 && *to_left > 0) { 2184 if ((wch = *src)) { 2185 length = wctomb(tmp, wch); 2186 } else { 2187 goto end; 2188 } 2189 2190 if (length < 0) 2191 goto end; 2192 2193 tmp_from = (XPointer) tmp; 2194 ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args); 2195 if (ret < 0) 2196 goto end; 2197 2198 src++; 2199 src_left--; 2200 } 2201 2202 end: 2203 /* error end */ 2204 if (save_from == (XPointer) src) { 2205 *from = (XPointer) ((const wchar_t *) *from + from_size); 2206 *from_left = 0; 2207 return -1; 2208 } 2209 2210 /* normal end */ 2211 *from = (XPointer) src; 2212 *from_left = src_left; 2213 2214 return 0; 2215 } 2216 2217 static int 2218 wcstocs( 2219 XlcConv conv, 2220 XPointer *from, 2221 int *from_left, 2222 XPointer *to, 2223 int *to_left, 2224 XPointer *args, 2225 int num_args) 2226 { 2227 int ret; 2228 XlcCharSet charset_old, charset = NULL; 2229 XPointer tmp_args[1]; 2230 2231 const wchar_t *inbufptr; 2232 int in_left; 2233 XPointer outbufptr; 2234 int out_left; 2235 tmp_args[0] = (XPointer) &charset; 2236 2237 ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2238 charset_old = charset; 2239 2240 while ( ret == 0 && *from_left && *to_left) { 2241 inbufptr = (const wchar_t *) *from; 2242 in_left = *from_left; 2243 outbufptr = *to; 2244 out_left = *to_left; 2245 ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2246 if (charset_old != charset) { 2247 *from = (XPointer) inbufptr; 2248 *from_left = in_left; 2249 *to = (XPointer) outbufptr; 2250 *to_left = out_left; 2251 break; 2252 } 2253 } 2254 2255 if (num_args > 0) 2256 *((XlcCharSet *) args[0]) = charset_old; 2257 2258 /* error end */ 2259 if (ret != 0) 2260 return( -1 ); 2261 2262 return(0); 2263 } 2264 2265 #ifdef STDCVT 2266 2267 static int 2268 stdc_wcstocs( 2269 XlcConv conv, 2270 XPointer *from, 2271 int *from_left, 2272 XPointer *to, 2273 int *to_left, 2274 XPointer *args, 2275 int num_args) 2276 { 2277 int ret; 2278 XlcCharSet charset_old, charset = NULL; 2279 XPointer tmp_args[1]; 2280 2281 const wchar_t *inbufptr; 2282 int in_left; 2283 XPointer outbufptr; 2284 int out_left; 2285 tmp_args[0] = (XPointer) &charset; 2286 2287 ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2288 charset_old = charset; 2289 2290 while ( ret == 0 && *from_left && *to_left ) { 2291 inbufptr = (const wchar_t *) *from; 2292 in_left = *from_left; 2293 outbufptr = *to; 2294 out_left = *to_left; 2295 ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2296 if (charset_old != charset) { 2297 *from = (XPointer) inbufptr; 2298 *from_left = in_left; 2299 *to = (XPointer) outbufptr; 2300 *to_left = out_left; 2301 break; 2302 } 2303 } 2304 2305 if (num_args > 0) 2306 *((XlcCharSet *) args[0]) = charset_old; 2307 2308 /* error end */ 2309 if (ret != 0) 2310 return( -1 ); 2311 2312 return(0); 2313 } 2314 2315 #endif 2316 2317 static int 2318 ctstombs( 2319 XlcConv conv, 2320 XPointer *from, 2321 int *from_left, 2322 XPointer *to, 2323 int *to_left, 2324 XPointer *args, 2325 int num_args) 2326 { 2327 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 2328 char *buf_ptr1 = buf; 2329 int buf_left1 = (*from_left); 2330 char *buf_ptr2 = buf_ptr1; 2331 int buf_left2; 2332 int unconv_num1 = 0, unconv_num2 = 0; 2333 2334 unconv_num1 = ctstowcs(conv, 2335 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2336 if (unconv_num1 < 0) 2337 goto ret; 2338 2339 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 2340 2341 unconv_num2 += wcstombs_org(conv, 2342 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2343 if (unconv_num2 < 0) 2344 goto ret; 2345 2346 ret: 2347 Xfree(buf); 2348 2349 return (unconv_num1 + unconv_num2); 2350 } 2351 2352 static int 2353 cstombs( 2354 XlcConv conv, 2355 XPointer *from, 2356 int *from_left, 2357 XPointer *to, 2358 int *to_left, 2359 XPointer *args, 2360 int num_args) 2361 { 2362 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 2363 char *buf_ptr1 = buf; 2364 int buf_left1 = (*from_left); 2365 char *buf_ptr2 = buf_ptr1; 2366 int buf_left2; 2367 int unconv_num1 = 0, unconv_num2 = 0; 2368 2369 unconv_num1 = cstowcs(conv, 2370 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2371 if (unconv_num1 < 0) 2372 goto ret; 2373 2374 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 2375 2376 unconv_num2 += wcstombs_org(conv, 2377 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2378 if (unconv_num2 < 0) 2379 goto ret; 2380 2381 ret: 2382 Xfree(buf); 2383 2384 return (unconv_num1 + unconv_num2); 2385 } 2386 2387 static int 2388 strtombs( 2389 XlcConv conv, 2390 XPointer *from, 2391 int *from_left, 2392 XPointer *to, 2393 int *to_left, 2394 XPointer *args, 2395 int num_args) 2396 { 2397 State state = (State) conv->state; 2398 XLCd lcd = state->lcd; 2399 2400 char *encoding; 2401 unsigned long mb, glyph_index; 2402 unsigned char ch; 2403 2404 int length; 2405 int unconv_num = 0; 2406 2407 CodeSet codeset; 2408 2409 const char *inbufptr = *from; 2410 char *outbufptr = *to; 2411 int from_size = *from_left; 2412 2413 while (*from_left && *to_left) { 2414 2415 ch = *inbufptr++; 2416 (*from_left)--; 2417 2418 /* null ? */ 2419 if (!ch) { 2420 if (outbufptr) {*outbufptr++ = '\0';} 2421 (*to_left)--; 2422 2423 continue; 2424 } 2425 2426 /* convert */ 2427 if (isleftside(ch)) { 2428 glyph_index = ch; 2429 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); 2430 } else { 2431 glyph_index = ch & GL; 2432 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); 2433 } 2434 2435 if (!codeset) { 2436 unconv_num++; 2437 continue; 2438 } 2439 2440 mb = gi_to_mb(glyph_index, codeset); 2441 if (codeset->parse_info) { 2442 Bool need_shift = False; 2443 switch (codeset->parse_info->type) { 2444 case E_LSL : 2445 if (codeset != state->GL_codeset) { 2446 need_shift = True; 2447 state->GL_codeset = codeset; 2448 } 2449 break; 2450 case E_LSR : 2451 if (codeset != state->GR_codeset) { 2452 need_shift = True; 2453 state->GR_codeset = codeset; 2454 } 2455 break; 2456 /* case E_SS */ 2457 default: 2458 need_shift = True; 2459 } 2460 2461 /* output shift sequence */ 2462 if (need_shift) { 2463 encoding = codeset->parse_info->encoding; 2464 length = strlen(encoding); 2465 if (*to_left < length) 2466 break; 2467 if (outbufptr) { 2468 memcpy(outbufptr, encoding, length); 2469 outbufptr += length; 2470 } 2471 (*to_left) -= length; 2472 } 2473 } 2474 2475 /* output characters */ 2476 length = codeset->length; 2477 if (*to_left < length) 2478 break; 2479 2480 if (outbufptr) { 2481 output_ulong_value(outbufptr, mb, length, XlcNONE); 2482 outbufptr += length; 2483 } 2484 2485 (*to_left) -= length; 2486 2487 } /* end of while */ 2488 2489 *from = (XPointer) ((const char *) *from + from_size); 2490 *from_left = 0; 2491 *to = (XPointer) outbufptr; 2492 2493 return unconv_num; 2494 } 2495 2496 static int 2497 strtowcs( 2498 XlcConv conv, 2499 XPointer *from, 2500 int *from_left, 2501 XPointer *to, 2502 int *to_left, 2503 XPointer *args, 2504 int num_args) 2505 { 2506 State state = (State) conv->state; 2507 XLCd lcd = state->lcd; 2508 2509 unsigned char ch; 2510 unsigned long glyph_index; 2511 wchar_t wc; 2512 2513 int unconv_num = 0; 2514 CodeSet codeset; 2515 2516 const char *inbufptr = *from; 2517 wchar_t *outbufptr = (wchar_t *)*to; 2518 int from_size = *from_left; 2519 2520 while (*from_left && *to_left) { 2521 2522 ch = *inbufptr++; 2523 (*from_left)--; 2524 2525 /* null ? */ 2526 if (!ch) { 2527 if (outbufptr) {*outbufptr++ = L'\0';} 2528 (*to_left)--; 2529 2530 continue; 2531 } 2532 2533 /* convert */ 2534 if (isleftside(ch)) { 2535 glyph_index = ch; 2536 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); 2537 } else { 2538 glyph_index = ch & GL; 2539 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); 2540 } 2541 2542 if (!codeset) { 2543 unconv_num++; 2544 continue; 2545 } 2546 2547 gi_to_wc(lcd, glyph_index, codeset, &wc); 2548 if (outbufptr) {*outbufptr++ = wc;} 2549 (*to_left)--; 2550 2551 } /* end of while */ 2552 2553 *from = (XPointer) ((const char *) *from + from_size); 2554 *from_left = 0; 2555 *to = (XPointer) outbufptr; 2556 2557 return unconv_num; 2558 } 2559 2560 static int 2561 stdc_strtowcs( 2562 XlcConv conv, 2563 XPointer *from, 2564 int *from_left, 2565 XPointer *to, 2566 int *to_left, 2567 XPointer *args, 2568 int num_args) 2569 { 2570 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 2571 char *buf_ptr1 = buf; 2572 int buf_left1 = (*from_left) * MB_CUR_MAX; 2573 char *buf_ptr2 = buf_ptr1; 2574 int buf_left2; 2575 int unconv_num1 = 0, unconv_num2 = 0; 2576 2577 unconv_num1 = strtombs(conv, 2578 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2579 if (unconv_num1 < 0) 2580 goto ret; 2581 2582 buf_left2 = buf_ptr1 - buf_ptr2; 2583 2584 unconv_num2 = stdc_mbstowcs(conv, 2585 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2586 if (unconv_num2 < 0) 2587 goto ret; 2588 2589 ret: 2590 Xfree(buf); 2591 2592 return (unconv_num1 + unconv_num2); 2593 } 2594 2595 /* -------------------------------------------------------------------------- */ 2596 /* Close */ 2597 /* -------------------------------------------------------------------------- */ 2598 2599 static void 2600 close_converter( 2601 XlcConv conv) 2602 { 2603 Xfree(conv->state); 2604 Xfree(conv->methods); 2605 Xfree(conv); 2606 } 2607 2608 /* -------------------------------------------------------------------------- */ 2609 /* Open */ 2610 /* -------------------------------------------------------------------------- */ 2611 2612 static XlcConv 2613 create_conv( 2614 XLCd lcd, 2615 XlcConvMethods methods) 2616 { 2617 XlcConv conv; 2618 State state; 2619 2620 conv = Xcalloc(1, sizeof(XlcConvRec)); 2621 if (conv == NULL) 2622 return (XlcConv) NULL; 2623 2624 conv->methods = Xmalloc(sizeof(XlcConvMethodsRec)); 2625 if (conv->methods == NULL) 2626 goto err; 2627 *conv->methods = *methods; 2628 conv->methods->reset = init_state; 2629 2630 conv->state = Xcalloc(1, sizeof(StateRec)); 2631 if (conv->state == NULL) 2632 goto err; 2633 2634 state = (State) conv->state; 2635 state->lcd = lcd; 2636 2637 _XlcResetConverter(conv); 2638 2639 return conv; 2640 2641 err: 2642 close_converter(conv); 2643 2644 return (XlcConv) NULL; 2645 } 2646 2647 static XlcConvMethodsRec mbstocts_methods = { 2648 close_converter, 2649 mbstocts, 2650 NULL 2651 }; 2652 2653 static XlcConv 2654 open_mbstocts( 2655 XLCd from_lcd, 2656 const char *from_type, 2657 XLCd to_lcd, 2658 const char *to_type) 2659 { 2660 return create_conv(from_lcd, &mbstocts_methods); 2661 } 2662 2663 static XlcConvMethodsRec mbstostr_methods = { 2664 close_converter, 2665 mbstostr, 2666 NULL 2667 }; 2668 2669 static XlcConv 2670 open_mbstostr( 2671 XLCd from_lcd, 2672 const char *from_type, 2673 XLCd to_lcd, 2674 const char *to_type) 2675 { 2676 return create_conv(from_lcd, &mbstostr_methods); 2677 } 2678 2679 static XlcConvMethodsRec mbstocs_methods = { 2680 close_converter, 2681 mbstocs, 2682 NULL 2683 }; 2684 2685 static XlcConv 2686 open_mbstocs( 2687 XLCd from_lcd, 2688 const char *from_type, 2689 XLCd to_lcd, 2690 const char *to_type) 2691 { 2692 return create_conv(from_lcd, &mbstocs_methods); 2693 } 2694 2695 static XlcConvMethodsRec mbtocs_methods = { 2696 close_converter, 2697 mbtocs, 2698 NULL 2699 }; 2700 2701 static XlcConv 2702 open_mbtocs( 2703 XLCd from_lcd, 2704 const char *from_type, 2705 XLCd to_lcd, 2706 const char *to_type) 2707 { 2708 return create_conv(from_lcd, &mbtocs_methods); 2709 } 2710 2711 static XlcConvMethodsRec ctstombs_methods = { 2712 close_converter, 2713 ctstombs, 2714 NULL 2715 }; 2716 2717 static XlcConv 2718 open_ctstombs( 2719 XLCd from_lcd, 2720 const char *from_type, 2721 XLCd to_lcd, 2722 const char *to_type) 2723 { 2724 return create_conv(from_lcd, &ctstombs_methods); 2725 } 2726 2727 static XlcConvMethodsRec cstombs_methods = { 2728 close_converter, 2729 cstombs, 2730 NULL 2731 }; 2732 2733 static XlcConv 2734 open_cstombs( 2735 XLCd from_lcd, 2736 const char *from_type, 2737 XLCd to_lcd, 2738 const char *to_type) 2739 { 2740 return create_conv(from_lcd, &cstombs_methods); 2741 } 2742 2743 static XlcConvMethodsRec strtombs_methods = { 2744 close_converter, 2745 strtombs, 2746 NULL 2747 }; 2748 2749 static XlcConv 2750 open_strtombs( 2751 XLCd from_lcd, 2752 const char *from_type, 2753 XLCd to_lcd, 2754 const char *to_type) 2755 { 2756 return create_conv(from_lcd, &strtombs_methods); 2757 } 2758 2759 #ifdef STDCVT 2760 2761 static XlcConvMethodsRec stdc_mbstowcs_methods = { 2762 close_converter, 2763 stdc_mbstowcs, 2764 NULL 2765 }; 2766 2767 static XlcConv 2768 open_stdc_mbstowcs( 2769 XLCd from_lcd, 2770 const char *from_type, 2771 XLCd to_lcd, 2772 const char *to_type) 2773 { 2774 return create_conv(from_lcd, &stdc_mbstowcs_methods); 2775 } 2776 2777 static XlcConvMethodsRec stdc_wcstombs_methods = { 2778 close_converter, 2779 stdc_wcstombs, 2780 NULL 2781 }; 2782 2783 static XlcConv 2784 open_stdc_wcstombs( 2785 XLCd from_lcd, 2786 const char *from_type, 2787 XLCd to_lcd, 2788 const char *to_type) 2789 { 2790 return create_conv(from_lcd, &stdc_wcstombs_methods); 2791 } 2792 2793 static XlcConvMethodsRec stdc_wcstocts_methods = { 2794 close_converter, 2795 stdc_wcstocts, 2796 NULL 2797 }; 2798 2799 static XlcConv 2800 open_stdc_wcstocts( 2801 XLCd from_lcd, 2802 const char *from_type, 2803 XLCd to_lcd, 2804 const char *to_type) 2805 { 2806 return create_conv(from_lcd, &stdc_wcstocts_methods); 2807 } 2808 2809 static XlcConvMethodsRec stdc_wcstostr_methods = { 2810 close_converter, 2811 stdc_wcstostr, 2812 NULL 2813 }; 2814 2815 static XlcConv 2816 open_stdc_wcstostr( 2817 XLCd from_lcd, 2818 const char *from_type, 2819 XLCd to_lcd, 2820 const char *to_type) 2821 { 2822 return create_conv(from_lcd, &stdc_wcstostr_methods); 2823 } 2824 2825 static XlcConvMethodsRec stdc_wcstocs_methods = { 2826 close_converter, 2827 stdc_wcstocs, 2828 NULL 2829 }; 2830 2831 static XlcConv 2832 open_stdc_wcstocs( 2833 XLCd from_lcd, 2834 const char *from_type, 2835 XLCd to_lcd, 2836 const char *to_type) 2837 { 2838 return create_conv(from_lcd, &stdc_wcstocs_methods); 2839 } 2840 2841 static XlcConvMethodsRec stdc_wctocs_methods = { 2842 close_converter, 2843 stdc_wctocs, 2844 NULL 2845 }; 2846 2847 static XlcConv 2848 open_stdc_wctocs( 2849 XLCd from_lcd, 2850 const char *from_type, 2851 XLCd to_lcd, 2852 const char *to_type) 2853 { 2854 return create_conv(from_lcd, &stdc_wctocs_methods); 2855 } 2856 2857 static XlcConvMethodsRec stdc_ctstowcs_methods = { 2858 close_converter, 2859 stdc_ctstowcs, 2860 NULL 2861 }; 2862 2863 static XlcConv 2864 open_stdc_ctstowcs( 2865 XLCd from_lcd, 2866 const char *from_type, 2867 XLCd to_lcd, 2868 const char *to_type) 2869 { 2870 return create_conv(from_lcd, &stdc_ctstowcs_methods); 2871 } 2872 2873 static XlcConvMethodsRec stdc_cstowcs_methods = { 2874 close_converter, 2875 stdc_cstowcs, 2876 NULL 2877 }; 2878 2879 static XlcConv 2880 open_stdc_cstowcs( 2881 XLCd from_lcd, 2882 const char *from_type, 2883 XLCd to_lcd, 2884 const char *to_type) 2885 { 2886 return create_conv(from_lcd, &stdc_cstowcs_methods); 2887 } 2888 2889 static XlcConvMethodsRec stdc_strtowcs_methods = { 2890 close_converter, 2891 stdc_strtowcs, 2892 NULL 2893 }; 2894 2895 static XlcConv 2896 open_stdc_strtowcs( 2897 XLCd from_lcd, 2898 const char *from_type, 2899 XLCd to_lcd, 2900 const char *to_type) 2901 { 2902 return create_conv(from_lcd, &stdc_strtowcs_methods); 2903 } 2904 2905 #endif /* STDCVT */ 2906 2907 static XlcConvMethodsRec mbstowcs_methods = { 2908 close_converter, 2909 mbstowcs_org, 2910 NULL 2911 }; 2912 2913 static XlcConv 2914 open_mbstowcs( 2915 XLCd from_lcd, 2916 const char *from_type, 2917 XLCd to_lcd, 2918 const char *to_type) 2919 { 2920 return create_conv(from_lcd, &mbstowcs_methods); 2921 } 2922 2923 static XlcConvMethodsRec wcstombs_methods = { 2924 close_converter, 2925 wcstombs_org, 2926 NULL 2927 }; 2928 2929 static XlcConv 2930 open_wcstombs( 2931 XLCd from_lcd, 2932 const char *from_type, 2933 XLCd to_lcd, 2934 const char *to_type) 2935 { 2936 return create_conv(from_lcd, &wcstombs_methods); 2937 } 2938 2939 static XlcConvMethodsRec wcstocts_methods = { 2940 close_converter, 2941 wcstocts, 2942 NULL 2943 }; 2944 2945 static XlcConv 2946 open_wcstocts( 2947 XLCd from_lcd, 2948 const char *from_type, 2949 XLCd to_lcd, 2950 const char *to_type) 2951 { 2952 return create_conv(from_lcd, &wcstocts_methods); 2953 } 2954 2955 static XlcConvMethodsRec wcstostr_methods = { 2956 close_converter, 2957 wcstostr, 2958 NULL 2959 }; 2960 2961 static XlcConv 2962 open_wcstostr( 2963 XLCd from_lcd, 2964 const char *from_type, 2965 XLCd to_lcd, 2966 const char *to_type) 2967 { 2968 return create_conv(from_lcd, &wcstostr_methods); 2969 } 2970 2971 static XlcConvMethodsRec wcstocs_methods = { 2972 close_converter, 2973 wcstocs, 2974 NULL 2975 }; 2976 2977 static XlcConv 2978 open_wcstocs( 2979 XLCd from_lcd, 2980 const char *from_type, 2981 XLCd to_lcd, 2982 const char *to_type) 2983 { 2984 return create_conv(from_lcd, &wcstocs_methods); 2985 } 2986 2987 static XlcConvMethodsRec wctocs_methods = { 2988 close_converter, 2989 wctocs, 2990 NULL 2991 }; 2992 2993 static XlcConv 2994 open_wctocs( 2995 XLCd from_lcd, 2996 const char *from_type, 2997 XLCd to_lcd, 2998 const char *to_type) 2999 { 3000 return create_conv(from_lcd, &wctocs_methods); 3001 } 3002 3003 static XlcConvMethodsRec ctstowcs_methods = { 3004 close_converter, 3005 ctstowcs, 3006 NULL 3007 }; 3008 3009 static XlcConv 3010 open_ctstowcs( 3011 XLCd from_lcd, 3012 const char *from_type, 3013 XLCd to_lcd, 3014 const char *to_type) 3015 { 3016 return create_conv(from_lcd, &ctstowcs_methods); 3017 } 3018 3019 static XlcConvMethodsRec cstowcs_methods = { 3020 close_converter, 3021 cstowcs, 3022 NULL 3023 }; 3024 3025 static XlcConv 3026 open_cstowcs( 3027 XLCd from_lcd, 3028 const char *from_type, 3029 XLCd to_lcd, 3030 const char *to_type) 3031 { 3032 return create_conv(from_lcd, &cstowcs_methods); 3033 } 3034 3035 static XlcConvMethodsRec strtowcs_methods = { 3036 close_converter, 3037 strtowcs, 3038 NULL 3039 }; 3040 3041 static XlcConv 3042 open_strtowcs( 3043 XLCd from_lcd, 3044 const char *from_type, 3045 XLCd to_lcd, 3046 const char *to_type) 3047 { 3048 return create_conv(from_lcd, &strtowcs_methods); 3049 } 3050 3051 /* -------------------------------------------------------------------------- */ 3052 /* Loader */ 3053 /* -------------------------------------------------------------------------- */ 3054 3055 XLCd 3056 _XlcGenericLoader( 3057 const char *name) 3058 { 3059 XLCd lcd; 3060 #ifdef STDCVT 3061 XLCdGenericPart *gen; 3062 #endif 3063 3064 lcd = _XlcCreateLC(name, _XlcGenericMethods); 3065 3066 if (lcd == NULL) 3067 return lcd; 3068 3069 default_GL_charset = _XlcGetCharSet("ISO8859-1:GL"); 3070 default_GR_charset = _XlcGetCharSet("ISO8859-1:GR"); 3071 3072 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts); 3073 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr); 3074 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); 3075 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); 3076 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs); 3077 _XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs); 3078 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); 3079 3080 #ifdef STDCVT 3081 gen = XLC_GENERIC_PART(lcd); 3082 3083 if (gen->use_stdc_env != True) { 3084 #endif 3085 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs); 3086 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs); 3087 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts); 3088 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr); 3089 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); 3090 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_wctocs); 3091 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs); 3092 _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_strtowcs); 3093 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); 3094 #ifdef STDCVT 3095 } 3096 #endif 3097 3098 #ifdef STDCVT 3099 if (gen->use_stdc_env == True) { 3100 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_stdc_mbstowcs); 3101 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_stdc_wcstombs); 3102 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_stdc_wcstocts); 3103 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_stdc_wcstostr); 3104 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_stdc_wcstocs); 3105 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_stdc_wctocs); 3106 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_stdc_ctstowcs); 3107 _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_stdc_strtowcs); 3108 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_stdc_cstowcs); 3109 } 3110 #endif 3111 3112 _XlcAddUtf8Converters(lcd); 3113 3114 return lcd; 3115 } 3116