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