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