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#ifndef 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 = *((const 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; 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 inbufptr = *from; 768 769 while (*from_left && *to_left) { 770 771 ch = *inbufptr++; 772 (*from_left)--; 773 774 /* null ? */ 775 if (!ch) { 776 if (outbufptr) {*outbufptr++ = L'\0';} 777 (*to_left)--; 778 779 /* error check */ 780 if (len_left) { 781 unconv_num += (length - len_left); 782 len_left = 0; 783 } 784 785 continue; 786 } 787 788 /* same mb char data */ 789 if (len_left) 790 goto output_one_wc; 791 792 /* next mb char data for single shift ? */ 793 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 794 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 795 if (codeset != NULL) { 796 length = len_left = codeset->length; 797 mb = 0; 798 continue; 799 } 800 } 801 802 /* next mb char data for byteM ? */ 803 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) 804 goto next_mb_char; 805 806 /* next mb char data for GL or GR side ? */ 807 if ((codeset = GLGR_parse_codeset(ch))) 808 goto next_mb_char; 809 810 /* can't find codeset for the ch */ 811 unconv_num++; 812 continue; 813 814next_mb_char: 815 length = len_left = codeset->length; 816 mb = 0; 817 818output_one_wc: 819 mb = (mb << 8) | ch; /* 1 byte left shift */ 820 len_left--; 821 822 /* last of one mb char data */ 823 if (!len_left) { 824 gi_to_wc(lcd, mb_to_gi(mb, codeset), codeset, &wc); 825 if (outbufptr) {*outbufptr++ = wc;} 826 (*to_left)--; 827 } 828 829 } /* end of while */ 830 831 /* error check on last char */ 832 if (len_left) { 833 inbufptr -= (length - len_left); 834 (*from_left) += (length - len_left); 835 unconv_num += (length - len_left); 836 } 837 838 *from = (XPointer) ((const char *) *from + from_size); 839 *from_left = 0; 840 *to = (XPointer) outbufptr; 841 842 return unconv_num; 843} 844 845static int 846stdc_mbstowcs( 847 XlcConv conv, 848 XPointer *from, 849 int *from_left, 850 XPointer *to, 851 int *to_left, 852 XPointer *args, 853 int num_args) 854{ 855 const char *src = *((const char **) from); 856 wchar_t *dst = *((wchar_t **) to); 857 int src_left = *from_left; 858 int dst_left = *to_left; 859 int length, unconv_num = 0; 860 861 while (src_left > 0 && dst_left > 0) { 862 length = mbtowc(dst, src, src_left); 863 864 if (length > 0) { 865 src += length; 866 src_left -= length; 867 if (dst) 868 dst++; 869 dst_left--; 870 } else if (length < 0) { 871 src++; 872 src_left--; 873 unconv_num++; 874 } else { 875 /* null ? */ 876 src++; 877 src_left--; 878 if (dst) 879 *dst++ = L'\0'; 880 dst_left--; 881 } 882 } 883 884 *from = (XPointer) src; 885 if (dst) 886 *to = (XPointer) dst; 887 *from_left = src_left; 888 *to_left = dst_left; 889 890 return unconv_num; 891} 892 893static int 894wcstombs_org( 895 XlcConv conv, 896 XPointer *from, 897 int *from_left, 898 XPointer *to, 899 int *to_left, 900 XPointer *args, 901 int num_args) 902{ 903 State state = (State) conv->state; 904 XLCd lcd = state->lcd; 905 906 char *encoding; 907 unsigned long mb, glyph_index; 908 wchar_t wc; 909 910 int length; 911 int unconv_num = 0; 912 913 CodeSet codeset; 914 915 const wchar_t *inbufptr = (const wchar_t *) *from; 916 char *outbufptr = *to; 917 int from_size = *from_left; 918 919 const char *default_string = XLC_PUBLIC(lcd, default_string); 920 int defstr_len = strlen(default_string); 921 922 923 while (*from_left && *to_left) { 924 925 wc = *inbufptr++; 926 (*from_left)--; 927 928 /* null ? */ 929 if (!wc) { 930 if (outbufptr) {*outbufptr++ = '\0';} 931 (*to_left)--; 932 933 continue; 934 } 935 936 /* convert */ 937 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 938 939 /* output default_string of XDefaultString() */ 940 if (*to_left < defstr_len) 941 break; 942 if (outbufptr) { 943 memcpy(outbufptr, default_string, defstr_len); 944 outbufptr += defstr_len; 945 } 946 (*to_left) -= defstr_len; 947 948 unconv_num++; 949 950 } else { 951 mb = gi_to_mb(glyph_index, codeset); 952 if (codeset->parse_info) { 953 Bool need_shift = False; 954 switch (codeset->parse_info->type) { 955 case E_LSL : 956 if (codeset != state->GL_codeset) { 957 need_shift = True; 958 state->GL_codeset = codeset; 959 } 960 break; 961 case E_LSR : 962 if (codeset != state->GR_codeset) { 963 need_shift = True; 964 state->GR_codeset = codeset; 965 } 966 break; 967 /* case E_SS */ 968 default: 969 need_shift = True; 970 } 971 972 /* output shift sequence */ 973 if (need_shift) { 974 encoding = codeset->parse_info->encoding; 975 length = strlen(encoding); 976 if (*to_left < length) 977 break; 978 if (outbufptr) { 979 memcpy(outbufptr, encoding, length); 980 outbufptr += length; 981 } 982 (*to_left) -= length; 983 } 984 } 985 986 /* output characters */ 987 length = codeset->length; 988 if (*to_left < length) 989 break; 990 991 if (outbufptr) { 992 output_ulong_value(outbufptr, mb, length, XlcNONE); 993 outbufptr += length; 994 } 995 996 (*to_left) -= length; 997 } 998 999 } /* end of while */ 1000 1001 *from = (XPointer) ((const wchar_t *) *from + from_size); 1002 *from_left = 0; 1003 *to = (XPointer) outbufptr; 1004 1005 return unconv_num; 1006} 1007 1008static int 1009stdc_wcstombs( 1010 XlcConv conv, 1011 XPointer *from, 1012 int *from_left, 1013 XPointer *to, 1014 int *to_left, 1015 XPointer *args, 1016 int num_args) 1017{ 1018 const wchar_t *src = *((const wchar_t **) from); 1019 char *dst = *((char **) to); 1020 int src_left = *from_left; 1021 int dst_left = *to_left; 1022 int length, unconv_num = 0; 1023 1024 while (src_left > 0 && dst_left >= MB_CUR_MAX) { 1025 length = wctomb(dst, *src); /* XXX */ 1026 1027 if (length > 0) { 1028 src++; 1029 src_left--; 1030 if (dst) 1031 dst += length; 1032 dst_left -= length; 1033 } else if (length < 0) { 1034 src++; 1035 src_left--; 1036 unconv_num++; 1037 } 1038 } 1039 1040 *from = (XPointer) src; 1041 if (dst) 1042 *to = (XPointer) dst; 1043 *from_left = src_left; 1044 *to_left = dst_left; 1045 1046 return unconv_num; 1047} 1048 1049static int 1050wcstocts( 1051 XlcConv conv, 1052 XPointer *from, 1053 int *from_left, 1054 XPointer *to, 1055 int *to_left, 1056 XPointer *args, 1057 int num_args) 1058{ 1059 State state = (State) conv->state; 1060 XLCd lcd = state->lcd; 1061 1062 unsigned long glyph_index; 1063 wchar_t wc; 1064 1065 int total_len, seq_len, name_len; 1066 int unconv_num = 0; 1067 Bool first_flag = True, standard_flag; 1068 XlcSide side; 1069 1070 CodeSet codeset; 1071 XlcCharSet charset, old_charset = NULL; 1072 const char *ct_sequence; 1073 1074 const wchar_t *inbufptr = (const wchar_t *) *from; 1075 char *outbufptr = *to; 1076 int from_size = *from_left; 1077 char *ext_seg_len = NULL; 1078 1079 while (*from_left && *to_left) { 1080 1081 wc = *inbufptr++; 1082 (*from_left)--; 1083 1084 /* null ? */ 1085 if (!wc) { 1086 if (outbufptr) {*outbufptr++ = '\0';} 1087 (*to_left)--; 1088 1089 continue; 1090 } 1091 1092 /* convert */ 1093 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 1094 unconv_num++; 1095 continue; 1096 } 1097 1098 /* parse charset */ 1099 if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { 1100 unconv_num++; 1101 continue; 1102 } 1103 1104 /* Standard Character Set Encoding ? */ 1105 standard_flag = charset->source == CSsrcStd ? True : False; 1106 1107 /* 1108 * Non-Standard Character Set Encoding 1109 * 1110 * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ 1111 * | esc sequence | M | L | encoding name | STX | 1112 * +-----+-----+-----+-----+-----+-----+-----+---- ----+-----+-----+ 1113 * 4bytes 1byte 1byte variable length 1byte 1114 * | | 1115 * +-----------------------------------------+ 1116 * name length = ((M - 128) * 128) + (L - 128) 1117 */ 1118 1119 /* make encoding data */ 1120 ct_sequence = charset->ct_sequence; 1121 side = charset->side; 1122 seq_len = strlen(ct_sequence); 1123 if (standard_flag) { 1124 name_len = 0; 1125 total_len = seq_len; 1126 } else { 1127 name_len = strlen(charset->encoding_name) + 1; 1128 total_len = seq_len + name_len + 2; 1129 } 1130 1131 /* output escape sequence of CT */ 1132 if ( (charset != old_charset) && 1133 !(first_flag && charset->string_encoding) ){ 1134 1135 if ( (ext_seg_len != NULL) && outbufptr) { 1136 int i = (outbufptr - ext_seg_len) - 2; 1137 *ext_seg_len++ = i / 128 + 128; 1138 *ext_seg_len = i % 128 + 128; 1139 ext_seg_len = NULL; 1140 } 1141 1142 if (*to_left < total_len + 1) { 1143 unconv_num++; 1144 break; 1145 } 1146 1147 if (outbufptr) { 1148 strcpy((char *)outbufptr, ct_sequence); 1149 outbufptr += seq_len; 1150 1151 if (!standard_flag) { 1152 const char *i = charset->encoding_name; 1153 ext_seg_len = outbufptr; 1154 outbufptr += 2; 1155 for (; *i ; i++) 1156 *outbufptr++ = ((*i >= 'A') && (*i <= 'Z')) ? 1157 *i - 'A' + 'a' : *i; 1158 *outbufptr++ = STX; 1159 } 1160 } 1161 1162 (*to_left) -= total_len; 1163 1164 first_flag = False; 1165 old_charset = charset; 1166 } 1167 1168 /* output glyph index */ 1169 if (codeset->ctconv) 1170 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 1171 if (*to_left < charset->char_size) { 1172 unconv_num++; 1173 break; 1174 } 1175 1176 if (outbufptr) { 1177 output_ulong_value(outbufptr, glyph_index, charset->char_size, side); 1178 outbufptr += charset->char_size; 1179 } 1180 1181 (*to_left) -= charset->char_size; 1182 1183 } /* end of while */ 1184 1185 if ( (ext_seg_len != NULL) && outbufptr) { 1186 int i = (outbufptr - ext_seg_len) - 2; 1187 *ext_seg_len++ = i / 128 + 128; 1188 *ext_seg_len = i % 128 + 128; 1189 } 1190 1191 *from = (XPointer) ((const wchar_t *) *from + from_size); 1192 *from_left = 0; 1193 *to = (XPointer) outbufptr; 1194 1195 return unconv_num; 1196} 1197 1198static int 1199stdc_wcstocts( 1200 XlcConv conv, 1201 XPointer *from, 1202 int *from_left, 1203 XPointer *to, 1204 int *to_left, 1205 XPointer *args, 1206 int num_args) 1207{ 1208 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1209 char *buf_ptr1 = buf; 1210 int buf_left1 = (*from_left) * MB_CUR_MAX; 1211 char *buf_ptr2 = buf_ptr1; 1212 int buf_left2; 1213 int unconv_num1 = 0, unconv_num2 = 0; 1214 1215 unconv_num1 = stdc_wcstombs(conv, 1216 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1217 if (unconv_num1 < 0) 1218 goto ret; 1219 1220 buf_left2 = buf_ptr1 - buf_ptr2; 1221 1222 unconv_num2 = mbstocts(conv, 1223 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1224 if (unconv_num2 < 0) 1225 goto ret; 1226 1227ret: 1228 Xfree(buf); 1229 1230 return (unconv_num1 + unconv_num2); 1231} 1232 1233static int 1234ctstowcs( 1235 XlcConv conv, 1236 XPointer *from, 1237 int *from_left, 1238 XPointer *to, 1239 int *to_left, 1240 XPointer *args, 1241 int num_args) 1242{ 1243 State state = (State) conv->state; 1244 XLCd lcd = state->lcd; 1245 1246 unsigned char ch; 1247 unsigned long glyph_index = 0; 1248 wchar_t wc; 1249 1250 int ctr_seq_len = 0, gi_len_left = 0, gi_len = 0; 1251 int unconv_num = 0; 1252 1253 CodeSet codeset = NULL; 1254 XlcCharSet charset_tmp; 1255 1256 const char *inbufptr; 1257 wchar_t *outbufptr = (wchar_t *) *to; 1258 int from_size = *from_left; 1259 1260 _XlcResetConverter(conv); /* ??? */ 1261 1262 if (from == NULL || *from == NULL) { 1263 _XlcResetConverter(conv); 1264 return( 0 ); 1265 } 1266 inbufptr = *from; 1267 1268 while (*from_left && *to_left) { 1269 1270 ch = *inbufptr++; 1271 (*from_left)--; 1272 1273 /* null ? */ 1274 if (!ch) { 1275 if (outbufptr) {*outbufptr++ = L'\0';} 1276 (*to_left)--; 1277 1278 /* error check */ 1279 if (gi_len_left) { 1280 unconv_num += (gi_len - gi_len_left); 1281 gi_len_left = 0; 1282 } 1283 1284 continue; 1285 } 1286 1287 /* same glyph_index data */ 1288 if (gi_len_left) 1289 goto output_one_wc; 1290 1291 /* control sequence ? */ 1292 if (ch == CSI) { 1293 if ( !ct_parse_csi(inbufptr - 1, &ctr_seq_len) ) 1294 goto skip_the_seg; 1295 1296 if (*from_left + 1 < ctr_seq_len) { 1297 inbufptr--; 1298 (*from_left)++; 1299 unconv_num += *from_left; 1300 break; 1301 } 1302 1303 /* skip the control sequence */ 1304 inbufptr += (ctr_seq_len - 1); 1305 *from_left -= (ctr_seq_len - 1); 1306 1307 continue; 1308 } 1309 1310 /* escape sequence ? */ 1311 if (ch == ESC) { 1312 if ( !ct_parse_charset(lcd, 1313 inbufptr - 1, &state->charset, &ctr_seq_len) ) 1314 goto skip_the_seg; 1315 1316 if (state->charset->side == XlcC0 || 1317 state->charset->side == XlcGL) 1318 { 1319 state->GL_charset = state->charset; 1320 } 1321 else if (state->charset->side == XlcC1 || 1322 state->charset->side == XlcGR) 1323 { 1324 state->GR_charset = state->charset; 1325 } 1326 else if (state->charset->side == XlcGLGR) 1327 { 1328 state->GL_charset = state->charset; 1329 state->GR_charset = state->charset; 1330 } 1331 1332 if (*from_left + 1 < ctr_seq_len) { 1333 inbufptr--; 1334 (*from_left)++; 1335 unconv_num += *from_left; 1336 break; 1337 } 1338 1339 /* skip the escape sequence */ 1340 inbufptr += (ctr_seq_len - 1); 1341 *from_left -= (ctr_seq_len - 1); 1342 1343 continue; 1344 } 1345 1346 /* check current state */ 1347 if (isleftside(ch)) 1348 state->charset = state->GL_charset; 1349 else 1350 state->charset = state->GR_charset; 1351 1352 gi_len = gi_len_left = state->charset->char_size; 1353 glyph_index = 0; 1354 1355output_one_wc: 1356 if (state->charset->side == XlcC1 || state->charset->side == XlcGR) 1357 glyph_index = (glyph_index << 8) | (ch & GL); 1358 else 1359 glyph_index = (glyph_index << 8) | ch; 1360 1361 gi_len_left--; 1362 1363 /* last of one glyph_index data */ 1364 if (!gi_len_left) { 1365 1366 /* segment conversion */ 1367 charset_tmp = state->charset; 1368 segment_conversion(lcd, &charset_tmp, &glyph_index); 1369 1370 /* get codeset */ 1371 if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, 1372 &codeset, &glyph_index) ) { 1373 unconv_num += gi_len; 1374 continue; 1375 } 1376 1377 /* convert glyph index to wicd char */ 1378 gi_to_wc(lcd, glyph_index, codeset, &wc); 1379 if (outbufptr) {*outbufptr++ = wc;} 1380 (*to_left)--; 1381 } 1382 1383 continue; 1384 1385skip_the_seg: 1386 /* skip until next escape or control sequence */ 1387 while ( *from_left ) { 1388 ch = *inbufptr++; 1389 (*from_left)--; 1390 unconv_num++; 1391 1392 if (ch == ESC || ch == CSI) { 1393 inbufptr--; 1394 (*from_left)++; 1395 unconv_num--; 1396 break; 1397 } 1398 } 1399 1400 if ( !(*from_left) ) 1401 break; 1402 1403 } /* end of while */ 1404 1405 /* error check on last char */ 1406 if (gi_len_left) { 1407 inbufptr -= (gi_len - gi_len_left); 1408 (*from_left) += (gi_len - gi_len_left); 1409 unconv_num += (gi_len - gi_len_left); 1410 } 1411 1412 *from = (XPointer) ((const char *) *from + from_size); 1413 *from_left = 0; 1414 *to = (XPointer) outbufptr; 1415 1416 return unconv_num; 1417} 1418 1419static int 1420cstowcs( 1421 XlcConv conv, 1422 XPointer *from, 1423 int *from_left, 1424 XPointer *to, 1425 int *to_left, 1426 XPointer *args, 1427 int num_args) 1428{ 1429 State state = (State) conv->state; 1430 XLCd lcd = state->lcd; 1431 1432 unsigned char ch; 1433 unsigned long glyph_index = 0; 1434 wchar_t wc; 1435 int gi_len_left = 0, gi_len = 0; 1436 1437 int unconv_num = 0; 1438 1439 CodeSet codeset = NULL; 1440 XlcCharSet charset, charset_tmp; 1441 1442 const char *inbufptr; 1443 wchar_t *outbufptr = (wchar_t *) *to; 1444 int from_size = *from_left; 1445 1446 if (from == NULL || *from == NULL) { 1447 return( 0 ); 1448 } 1449 1450 inbufptr = *from; 1451 1452 charset = (XlcCharSet) args[0]; 1453 1454 while (*from_left && *to_left) { 1455 1456 if (!gi_len_left) { 1457 gi_len_left = gi_len = charset->char_size; 1458 glyph_index = 0; 1459 } 1460 1461 ch = *inbufptr++; 1462 (*from_left)--; 1463 1464 /* null ? */ 1465 if (!ch) { 1466 if (outbufptr) {*outbufptr++ = L'\0';} 1467 (*to_left)--; 1468 1469 /* error check */ 1470 if (gi_len_left) { 1471 unconv_num += (gi_len - gi_len_left); 1472 gi_len_left = 0; 1473 } 1474 continue; 1475 } 1476 1477 if (charset->side == XlcC1 || charset->side == XlcGR) 1478 glyph_index = (glyph_index << 8) | (ch & GL); 1479 else 1480 glyph_index = (glyph_index << 8) | ch; 1481 1482 gi_len_left--; 1483 1484 /* last of one glyph_index data */ 1485 if (!gi_len_left) { 1486 1487 /* segment conversion */ 1488 charset_tmp = charset; 1489 segment_conversion(lcd, &charset_tmp, &glyph_index); 1490 1491 /* get codeset */ 1492 if ( !_XlcGetCodeSetFromCharSet(lcd, charset_tmp, 1493 &codeset, &glyph_index) ) { 1494 unconv_num += gi_len; 1495 continue; 1496 } 1497 1498 /* convert glyph index to wicd char */ 1499 gi_to_wc(lcd, glyph_index, codeset, &wc); 1500 if (outbufptr) {*outbufptr++ = wc;} 1501 (*to_left)--; 1502 } 1503 1504 } /* end of while */ 1505 1506 /* error check on last char */ 1507 if (gi_len_left) { 1508 inbufptr -= (gi_len - gi_len_left); 1509 (*from_left) += (gi_len - gi_len_left); 1510 unconv_num += (gi_len - gi_len_left); 1511 } 1512 1513 *from = (XPointer) ((const char *) *from + from_size); 1514 *from_left = 0; 1515 *to = (XPointer) outbufptr; 1516 1517 return unconv_num; 1518} 1519 1520static int 1521stdc_ctstowcs( 1522 XlcConv conv, 1523 XPointer *from, 1524 int *from_left, 1525 XPointer *to, 1526 int *to_left, 1527 XPointer *args, 1528 int num_args) 1529{ 1530 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1531 char *buf_ptr1 = buf; 1532 int buf_left1 = (*from_left) * MB_CUR_MAX; 1533 char *buf_ptr2 = buf_ptr1; 1534 int buf_left2; 1535 int unconv_num1 = 0, unconv_num2 = 0; 1536 1537 unconv_num1 = ctstombs(conv, 1538 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1539 if (unconv_num1 < 0) 1540 goto ret; 1541 1542 buf_left2 = buf_ptr1 - buf_ptr2; 1543 1544 unconv_num2 = stdc_mbstowcs(conv, 1545 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1546 if (unconv_num2 < 0) 1547 goto ret; 1548 1549ret: 1550 Xfree(buf); 1551 1552 return (unconv_num1 + unconv_num2); 1553} 1554 1555static int 1556stdc_cstowcs( 1557 XlcConv conv, 1558 XPointer *from, 1559 int *from_left, 1560 XPointer *to, 1561 int *to_left, 1562 XPointer *args, 1563 int num_args) 1564{ 1565 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 1566 char *buf_ptr1 = buf; 1567 int buf_left1 = (*from_left) * MB_CUR_MAX; 1568 char *buf_ptr2 = buf_ptr1; 1569 int buf_left2; 1570 int unconv_num1 = 0, unconv_num2 = 0; 1571 1572 unconv_num1 = cstombs(conv, 1573 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1574 if (unconv_num1 < 0) 1575 goto ret; 1576 1577 buf_left2 = buf_ptr1 - buf_ptr2; 1578 1579 unconv_num2 = stdc_mbstowcs(conv, 1580 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1581 if (unconv_num2 < 0) 1582 goto ret; 1583 1584ret: 1585 Xfree(buf); 1586 1587 return (unconv_num1 + unconv_num2); 1588} 1589 1590static int 1591mbstocts( 1592 XlcConv conv, 1593 XPointer *from, 1594 int *from_left, 1595 XPointer *to, 1596 int *to_left, 1597 XPointer *args, 1598 int num_args) 1599{ 1600 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 1601 char *buf_ptr1 = buf; 1602 int buf_left1 = (*from_left); 1603 char *buf_ptr2 = buf_ptr1; 1604 int buf_left2; 1605 int unconv_num1 = 0, unconv_num2 = 0; 1606 1607 unconv_num1 = mbstowcs_org(conv, 1608 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 1609 if (unconv_num1 < 0) 1610 goto ret; 1611 1612 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 1613 1614 unconv_num2 += wcstocts(conv, 1615 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 1616 if (unconv_num2 < 0) 1617 goto ret; 1618 1619ret: 1620 Xfree(buf); 1621 1622 return (unconv_num1 + unconv_num2); 1623} 1624 1625static int 1626mbstostr( 1627 XlcConv conv, 1628 XPointer *from, 1629 int *from_left, 1630 XPointer *to, 1631 int *to_left, 1632 XPointer *args, 1633 int num_args) 1634{ 1635 State state = (State) conv->state; 1636 XLCd lcd = state->lcd; 1637 1638 unsigned char ch; 1639 unsigned long mb = 0; 1640 1641 int length = 0, len_left = 0; 1642 int unconv_num = 0; 1643 int num; 1644 1645 CodeSet codeset = NULL; 1646 1647 const char *inbufptr; 1648 char *outbufptr = *to; 1649 int from_size = *from_left; 1650 1651 unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); 1652 1653 if (from == NULL || *from == NULL) { 1654 _XlcResetConverter(conv); 1655 return( 0 ); 1656 } 1657 1658 inbufptr = *from; 1659 1660 while (*from_left && *to_left) { 1661 1662 ch = *inbufptr++; 1663 (*from_left)--; 1664 1665 /* null ? */ 1666 if (!ch) { 1667 if (outbufptr) {*outbufptr++ = '\0';} 1668 (*to_left)--; 1669 1670 /* error check */ 1671 if (len_left) { 1672 unconv_num += (length - len_left); 1673 len_left = 0; 1674 } 1675 1676 continue; 1677 } 1678 1679 /* same mb char data */ 1680 if (len_left) 1681 goto output_one_mb; 1682 1683 /* next mb char data for single shift ? */ 1684 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 1685 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 1686 if (codeset != NULL) { 1687 length = len_left = codeset->length; 1688 mb = 0; 1689 continue; 1690 } 1691 } 1692 1693 /* next char data : byteM ? */ 1694 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) 1695 goto next_mb_char; 1696 1697 /* next char data : GL or GR side ? */ 1698 if ((codeset = GLGR_parse_codeset(ch))) 1699 goto next_mb_char; 1700 1701 /* can't find codeset for the ch */ 1702 unconv_num++; 1703 continue; 1704 1705next_mb_char: 1706 length = len_left = codeset->length; 1707 mb = 0; 1708 1709output_one_mb: 1710 mb = (mb << 8) | ch; /* 1 byte left shift */ 1711 len_left--; 1712 1713 /* last of one mb char data */ 1714 if (!len_left) { 1715 if (check_string_encoding(codeset)) { 1716 if (outbufptr) {*outbufptr++ = mb & 0xff;} 1717 (*to_left)--; 1718 } else { 1719 unconv_num++; 1720 } 1721 } 1722 1723 } /* end of while */ 1724 1725 /* error check on last char */ 1726 if (len_left) { 1727 inbufptr -= (length - len_left); 1728 (*from_left) += (length - len_left); 1729 unconv_num += (length - len_left); 1730 } 1731 1732 *from = (XPointer) ((const char *) *from + from_size); 1733 *from_left = 0; 1734 *to = (XPointer) outbufptr; 1735 1736 return unconv_num; 1737} 1738 1739static int 1740mbtocs( 1741 XlcConv conv, 1742 XPointer *from, 1743 int *from_left, 1744 XPointer *to, 1745 int *to_left, 1746 XPointer *args, 1747 int num_args) 1748{ 1749 State state = (State) conv->state; 1750 XLCd lcd = state->lcd; 1751 1752 unsigned char ch; 1753 unsigned long mb = 0; 1754 unsigned long glyph_index; 1755 1756 int length = 0, len_left = 0, char_len; 1757 int unconv_num = 0; 1758 int num; 1759 XlcSide side; 1760 1761 CodeSet codeset = NULL; 1762 XlcCharSet charset = NULL; 1763 1764 const char *inbufptr; 1765 char *outbufptr = *to; 1766 int from_size = *from_left; 1767 1768 unsigned char *mb_parse_table = XLC_GENERIC(lcd, mb_parse_table); 1769 1770 if (from == NULL || *from == NULL) { 1771 _XlcResetConverter(conv); 1772 return( 0 ); 1773 } 1774 1775 inbufptr = *from; 1776 1777 while (*from_left && *to_left) { 1778 1779 ch = *inbufptr++; 1780 (*from_left)--; 1781 1782 /* null ? */ 1783 if (!ch) { 1784 unconv_num = 1; 1785 if (len_left) 1786 unconv_num += (length - len_left); 1787 break; 1788 } 1789 1790 /* same mb char data */ 1791 if (len_left) 1792 goto output; 1793 1794 /* next mb char data for single shift ? */ 1795 if (mb_parse_table && (num = mb_parse_table[ch]) ) { 1796 codeset = mb_parse_codeset(state, num, &inbufptr, from_left); 1797 if (codeset != NULL) { 1798 length = len_left = codeset->length; 1799 mb = 0; 1800 continue; 1801 } 1802 } 1803 1804 /* next mb char data for byteM ? */ 1805 if ((codeset = byteM_parse_codeset(lcd, (inbufptr - 1)))) 1806 goto next_mb_char; 1807 1808 /* next mb char data for GL or GR side ? */ 1809 if ((codeset = GLGR_parse_codeset(ch))) 1810 goto next_mb_char; 1811 1812 /* can't find codeset for the ch */ 1813 unconv_num = 1; 1814 break; 1815 1816next_mb_char: 1817 length = len_left = codeset->length; 1818 mb = 0; 1819 1820output: 1821 mb = (mb << 8) | ch; /* 1 byte left shift */ 1822 len_left--; 1823 1824 /* last of one mb char data */ 1825 if (!len_left) { 1826 glyph_index = mb_to_gi(mb, codeset); 1827 if (!(charset = gi_parse_charset(glyph_index, codeset))) { 1828 unconv_num = length; 1829 break; 1830 } 1831 char_len = charset->char_size; 1832 side = charset->side; 1833 1834 /* output glyph index */ 1835 if (codeset->ctconv) 1836 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 1837 if (*to_left < char_len) { 1838 unconv_num = length; 1839 break; 1840 } 1841 1842 if (outbufptr) { 1843 output_ulong_value(outbufptr, glyph_index, char_len, side); 1844 outbufptr += char_len; 1845 } 1846 1847 (*to_left) -= char_len; 1848 1849 break; 1850 } 1851 1852 } /* end of while */ 1853 1854 /* error end */ 1855 if (unconv_num) { 1856 *from = (XPointer) ((const char *) *from + from_size); 1857 *from_left = 0; 1858 *to = (XPointer) outbufptr; 1859 return -1; 1860 } 1861 1862 /* normal end */ 1863 *from = (XPointer) inbufptr; 1864 *to = (XPointer) outbufptr; 1865 1866 if (num_args > 0) 1867 *((XlcCharSet *) args[0]) = charset; 1868 1869 return 0; 1870} 1871 1872static int 1873mbstocs( 1874 XlcConv conv, 1875 XPointer *from, 1876 int *from_left, 1877 XPointer *to, 1878 int *to_left, 1879 XPointer *args, 1880 int num_args) 1881{ 1882 int ret; 1883 XlcCharSet charset_old, charset = NULL; 1884 XPointer tmp_args[1]; 1885 1886 const char *inbufptr; 1887 int in_left; 1888 char *outbufptr; 1889 int out_left; 1890 tmp_args[0] = (XPointer) &charset; 1891 1892 ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); 1893 charset_old = charset; 1894 1895 while ( ret == 0 && *from_left && *to_left) { 1896 inbufptr = *from; 1897 in_left = *from_left; 1898 outbufptr = *to; 1899 out_left = *to_left; 1900 ret = mbtocs(conv, from, from_left, to, to_left, tmp_args, 1); 1901 if (charset_old != charset) { 1902 *from = (XPointer) inbufptr; 1903 *from_left = in_left; 1904 *to = (XPointer) outbufptr; 1905 *to_left = out_left; 1906 break; 1907 } 1908 } 1909 1910 if (num_args > 0) 1911 *((XlcCharSet *) args[0]) = charset_old; 1912 1913 /* error end */ 1914 if (ret != 0) 1915 return( -1 ); 1916 1917 return(0); 1918} 1919 1920static int 1921wcstostr( 1922 XlcConv conv, 1923 XPointer *from, 1924 int *from_left, 1925 XPointer *to, 1926 int *to_left, 1927 XPointer *args, 1928 int num_args) 1929{ 1930 State state = (State) conv->state; 1931 XLCd lcd = state->lcd; 1932 1933 char *encoding; 1934 unsigned long mb, glyph_index; 1935 wchar_t wc; 1936 1937 int length; 1938 int unconv_num = 0; 1939 1940 CodeSet codeset; 1941 1942 const wchar_t *inbufptr = (const wchar_t *) *from; 1943 char *outbufptr = *to; 1944 int from_size = *from_left; 1945 1946 const char *default_string = XLC_PUBLIC(lcd, default_string); 1947 int defstr_len = strlen(default_string); 1948 1949 while (*from_left && *to_left) { 1950 1951 wc = *inbufptr++; 1952 (*from_left)--; 1953 1954 /* null ? */ 1955 if (!wc) { 1956 if (outbufptr) {*outbufptr++ = '\0';} 1957 (*to_left)--; 1958 1959 continue; 1960 } 1961 1962 /* convert */ 1963 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 1964 1965 /* output default_string of XDefaultString() */ 1966 if (*to_left < defstr_len) 1967 break; 1968 if (outbufptr) { 1969 memcpy(outbufptr, default_string, defstr_len); 1970 outbufptr += defstr_len; 1971 } 1972 (*to_left) -= defstr_len; 1973 1974 unconv_num++; 1975 1976 } else { 1977 mb = gi_to_mb(glyph_index, codeset); 1978 1979 if (check_string_encoding(codeset)) { 1980 if (codeset->parse_info) { 1981 Bool need_shift = False; 1982 switch (codeset->parse_info->type) { 1983 case E_LSL : 1984 if (codeset != state->GL_codeset) { 1985 need_shift = True; 1986 state->GL_codeset = codeset; 1987 } 1988 break; 1989 case E_LSR : 1990 if (codeset != state->GR_codeset) { 1991 need_shift = True; 1992 state->GR_codeset = codeset; 1993 } 1994 break; 1995 /* case E_SS */ 1996 default: 1997 need_shift = True; 1998 } 1999 2000 /* output shift sequence */ 2001 if (need_shift) { 2002 encoding = codeset->parse_info->encoding; 2003 length = strlen(encoding); 2004 if (*to_left < length) 2005 break; 2006 2007 if (outbufptr) { 2008 memcpy(outbufptr, encoding, length); 2009 outbufptr += length; 2010 } 2011 (*to_left) -= length; 2012 } 2013 } 2014 2015 /* output characters */ 2016 length = codeset->length; 2017 if (*to_left < length) 2018 break; 2019 2020 if (outbufptr) { 2021 output_ulong_value(outbufptr, mb, length, XlcNONE); 2022 outbufptr += length; 2023 } 2024 2025 (*to_left) -= length; 2026 } else { 2027 unconv_num++; 2028 } 2029 } 2030 2031 } /* end of while */ 2032 2033 *from = (XPointer) ((const wchar_t *) *from + from_size); 2034 *from_left = 0; 2035 *to = (XPointer) outbufptr; 2036 2037 return unconv_num; 2038} 2039 2040static int 2041stdc_wcstostr( 2042 XlcConv conv, 2043 XPointer *from, 2044 int *from_left, 2045 XPointer *to, 2046 int *to_left, 2047 XPointer *args, 2048 int num_args) 2049{ 2050 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 2051 char *buf_ptr1 = buf; 2052 int buf_left1 = (*from_left) * MB_CUR_MAX; 2053 char *buf_ptr2 = buf_ptr1; 2054 int buf_left2; 2055 int unconv_num1 = 0, unconv_num2 = 0; 2056 2057 unconv_num1 = stdc_wcstombs(conv, 2058 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2059 if (unconv_num1 < 0) 2060 goto ret; 2061 2062 buf_left2 = buf_ptr1 - buf_ptr2; 2063 2064 unconv_num2 = mbstostr(conv, 2065 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2066 if (unconv_num2 < 0) 2067 goto ret; 2068 2069ret: 2070 Xfree(buf); 2071 2072 return (unconv_num1 + unconv_num2); 2073} 2074 2075static int 2076wctocs( 2077 XlcConv conv, 2078 XPointer *from, 2079 int *from_left, 2080 XPointer *to, 2081 int *to_left, 2082 XPointer *args, 2083 int num_args) 2084{ 2085 State state = (State) conv->state; 2086 XLCd lcd = state->lcd; 2087 2088 wchar_t wc; 2089 unsigned long glyph_index; 2090 2091 int char_len; 2092 int unconv_num = 0; 2093 XlcSide side; 2094 2095 CodeSet codeset; 2096 XlcCharSet charset = NULL; 2097 2098 const wchar_t *inbufptr = (const wchar_t *) *from; 2099 char *outbufptr = *to; 2100 int from_size = *from_left; 2101 2102 if (*from_left && *to_left) { 2103 2104 wc = *inbufptr++; 2105 (*from_left)--; 2106 2107 /* null ? */ 2108 if (!wc) { 2109 unconv_num = 1; 2110 goto end; 2111 } 2112 2113 /* convert */ 2114 if ( !wc_to_gi(lcd, wc, &glyph_index, &codeset) ) { 2115 unconv_num = 1; 2116 goto end; 2117 } 2118 2119 if ( !(charset = gi_parse_charset(glyph_index, codeset)) ) { 2120 unconv_num = 1; 2121 goto end; 2122 } 2123 char_len = charset->char_size; 2124 side = charset->side; 2125 2126 /* output glyph index */ 2127 if (codeset->ctconv) 2128 glyph_index = conv_to_dest(codeset->ctconv, glyph_index); 2129 if (*to_left < char_len) { 2130 unconv_num++; 2131 goto end; 2132 } 2133 2134 if (outbufptr) { 2135 output_ulong_value(outbufptr, glyph_index, char_len, side); 2136 outbufptr += char_len; 2137 } 2138 2139 (*to_left) -= char_len; 2140 2141 } 2142 2143end: 2144 2145 /* error end */ 2146 if (unconv_num) { 2147 *from = (XPointer) ((const wchar_t *) *from + from_size); 2148 *from_left = 0; 2149 *to = (XPointer) outbufptr; 2150 return -1; 2151 } 2152 2153 /* normal end */ 2154 *from = (XPointer) inbufptr; 2155 *to = (XPointer) outbufptr; 2156 2157 if (num_args > 0) 2158 *((XlcCharSet *) args[0]) = charset; 2159 2160 return 0; 2161} 2162 2163static int 2164stdc_wctocs( 2165 XlcConv conv, 2166 XPointer *from, 2167 int *from_left, 2168 XPointer *to, 2169 int *to_left, 2170 XPointer *args, 2171 int num_args) 2172{ 2173 const wchar_t *src = *((const wchar_t **) from); 2174 wchar_t wch; 2175 XPointer tmp_from, save_from = *from; 2176 char tmp[32]; 2177 int length, ret, src_left = *from_left; 2178 int from_size = *from_left; 2179 2180 if (src_left > 0 && *to_left > 0) { 2181 if ((wch = *src)) { 2182 length = wctomb(tmp, wch); 2183 } else { 2184 goto end; 2185 } 2186 2187 if (length < 0) 2188 goto end; 2189 2190 tmp_from = (XPointer) tmp; 2191 ret = mbtocs(conv, &tmp_from, &length, to, to_left, args, num_args); 2192 if (ret < 0) 2193 goto end; 2194 2195 src++; 2196 src_left--; 2197 } 2198 2199end: 2200 /* error end */ 2201 if (save_from == (XPointer) src) { 2202 *from = (XPointer) ((const wchar_t *) *from + from_size); 2203 *from_left = 0; 2204 return -1; 2205 } 2206 2207 /* normal end */ 2208 *from = (XPointer) src; 2209 *from_left = src_left; 2210 2211 return 0; 2212} 2213 2214static int 2215wcstocs( 2216 XlcConv conv, 2217 XPointer *from, 2218 int *from_left, 2219 XPointer *to, 2220 int *to_left, 2221 XPointer *args, 2222 int num_args) 2223{ 2224 int ret; 2225 XlcCharSet charset_old, charset = NULL; 2226 XPointer tmp_args[1]; 2227 2228 const wchar_t *inbufptr; 2229 int in_left; 2230 XPointer outbufptr; 2231 int out_left; 2232 tmp_args[0] = (XPointer) &charset; 2233 2234 ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2235 charset_old = charset; 2236 2237 while ( ret == 0 && *from_left && *to_left) { 2238 inbufptr = (const wchar_t *) *from; 2239 in_left = *from_left; 2240 outbufptr = *to; 2241 out_left = *to_left; 2242 ret = wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2243 if (charset_old != charset) { 2244 *from = (XPointer) inbufptr; 2245 *from_left = in_left; 2246 *to = (XPointer) outbufptr; 2247 *to_left = out_left; 2248 break; 2249 } 2250 } 2251 2252 if (num_args > 0) 2253 *((XlcCharSet *) args[0]) = charset_old; 2254 2255 /* error end */ 2256 if (ret != 0) 2257 return( -1 ); 2258 2259 return(0); 2260} 2261 2262#ifdef STDCVT 2263 2264static int 2265stdc_wcstocs( 2266 XlcConv conv, 2267 XPointer *from, 2268 int *from_left, 2269 XPointer *to, 2270 int *to_left, 2271 XPointer *args, 2272 int num_args) 2273{ 2274 int ret; 2275 XlcCharSet charset_old, charset = NULL; 2276 XPointer tmp_args[1]; 2277 2278 const wchar_t *inbufptr; 2279 int in_left; 2280 XPointer outbufptr; 2281 int out_left; 2282 tmp_args[0] = (XPointer) &charset; 2283 2284 ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2285 charset_old = charset; 2286 2287 while ( ret == 0 && *from_left && *to_left ) { 2288 inbufptr = (const wchar_t *) *from; 2289 in_left = *from_left; 2290 outbufptr = *to; 2291 out_left = *to_left; 2292 ret = stdc_wctocs(conv, from, from_left, to, to_left, tmp_args, 1); 2293 if (charset_old != charset) { 2294 *from = (XPointer) inbufptr; 2295 *from_left = in_left; 2296 *to = (XPointer) outbufptr; 2297 *to_left = out_left; 2298 break; 2299 } 2300 } 2301 2302 if (num_args > 0) 2303 *((XlcCharSet *) args[0]) = charset_old; 2304 2305 /* error end */ 2306 if (ret != 0) 2307 return( -1 ); 2308 2309 return(0); 2310} 2311 2312#endif 2313 2314static int 2315ctstombs( 2316 XlcConv conv, 2317 XPointer *from, 2318 int *from_left, 2319 XPointer *to, 2320 int *to_left, 2321 XPointer *args, 2322 int num_args) 2323{ 2324 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 2325 char *buf_ptr1 = buf; 2326 int buf_left1 = (*from_left); 2327 char *buf_ptr2 = buf_ptr1; 2328 int buf_left2; 2329 int unconv_num1 = 0, unconv_num2 = 0; 2330 2331 unconv_num1 = ctstowcs(conv, 2332 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2333 if (unconv_num1 < 0) 2334 goto ret; 2335 2336 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 2337 2338 unconv_num2 += wcstombs_org(conv, 2339 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2340 if (unconv_num2 < 0) 2341 goto ret; 2342 2343ret: 2344 Xfree(buf); 2345 2346 return (unconv_num1 + unconv_num2); 2347} 2348 2349static int 2350cstombs( 2351 XlcConv conv, 2352 XPointer *from, 2353 int *from_left, 2354 XPointer *to, 2355 int *to_left, 2356 XPointer *args, 2357 int num_args) 2358{ 2359 XPointer buf = Xmalloc((*from_left) * sizeof(wchar_t)); 2360 char *buf_ptr1 = buf; 2361 int buf_left1 = (*from_left); 2362 char *buf_ptr2 = buf_ptr1; 2363 int buf_left2; 2364 int unconv_num1 = 0, unconv_num2 = 0; 2365 2366 unconv_num1 = cstowcs(conv, 2367 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2368 if (unconv_num1 < 0) 2369 goto ret; 2370 2371 buf_left2 = (buf_ptr1 - buf_ptr2) / sizeof(wchar_t); 2372 2373 unconv_num2 += wcstombs_org(conv, 2374 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2375 if (unconv_num2 < 0) 2376 goto ret; 2377 2378ret: 2379 Xfree(buf); 2380 2381 return (unconv_num1 + unconv_num2); 2382} 2383 2384static int 2385strtombs( 2386 XlcConv conv, 2387 XPointer *from, 2388 int *from_left, 2389 XPointer *to, 2390 int *to_left, 2391 XPointer *args, 2392 int num_args) 2393{ 2394 State state = (State) conv->state; 2395 XLCd lcd = state->lcd; 2396 2397 char *encoding; 2398 unsigned long mb, glyph_index; 2399 unsigned char ch; 2400 2401 int length; 2402 int unconv_num = 0; 2403 2404 CodeSet codeset; 2405 2406 const char *inbufptr = *from; 2407 char *outbufptr = *to; 2408 int from_size = *from_left; 2409 2410 while (*from_left && *to_left) { 2411 2412 ch = *inbufptr++; 2413 (*from_left)--; 2414 2415 /* null ? */ 2416 if (!ch) { 2417 if (outbufptr) {*outbufptr++ = '\0';} 2418 (*to_left)--; 2419 2420 continue; 2421 } 2422 2423 /* convert */ 2424 if (isleftside(ch)) { 2425 glyph_index = ch; 2426 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); 2427 } else { 2428 glyph_index = ch & GL; 2429 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); 2430 } 2431 2432 if (!codeset) { 2433 unconv_num++; 2434 continue; 2435 } 2436 2437 mb = gi_to_mb(glyph_index, codeset); 2438 if (codeset->parse_info) { 2439 Bool need_shift = False; 2440 switch (codeset->parse_info->type) { 2441 case E_LSL : 2442 if (codeset != state->GL_codeset) { 2443 need_shift = True; 2444 state->GL_codeset = codeset; 2445 } 2446 break; 2447 case E_LSR : 2448 if (codeset != state->GR_codeset) { 2449 need_shift = True; 2450 state->GR_codeset = codeset; 2451 } 2452 break; 2453 /* case E_SS */ 2454 default: 2455 need_shift = True; 2456 } 2457 2458 /* output shift sequence */ 2459 if (need_shift) { 2460 encoding = codeset->parse_info->encoding; 2461 length = strlen(encoding); 2462 if (*to_left < length) 2463 break; 2464 if (outbufptr) { 2465 memcpy(outbufptr, encoding, length); 2466 outbufptr += length; 2467 } 2468 (*to_left) -= length; 2469 } 2470 } 2471 2472 /* output characters */ 2473 length = codeset->length; 2474 if (*to_left < length) 2475 break; 2476 2477 if (outbufptr) { 2478 output_ulong_value(outbufptr, mb, length, XlcNONE); 2479 outbufptr += length; 2480 } 2481 2482 (*to_left) -= length; 2483 2484 } /* end of while */ 2485 2486 *from = (XPointer) ((const char *) *from + from_size); 2487 *from_left = 0; 2488 *to = (XPointer) outbufptr; 2489 2490 return unconv_num; 2491} 2492 2493static int 2494strtowcs( 2495 XlcConv conv, 2496 XPointer *from, 2497 int *from_left, 2498 XPointer *to, 2499 int *to_left, 2500 XPointer *args, 2501 int num_args) 2502{ 2503 State state = (State) conv->state; 2504 XLCd lcd = state->lcd; 2505 2506 unsigned char ch; 2507 unsigned long glyph_index; 2508 wchar_t wc; 2509 2510 int unconv_num = 0; 2511 CodeSet codeset; 2512 2513 const char *inbufptr = *from; 2514 wchar_t *outbufptr = (wchar_t *)*to; 2515 int from_size = *from_left; 2516 2517 while (*from_left && *to_left) { 2518 2519 ch = *inbufptr++; 2520 (*from_left)--; 2521 2522 /* null ? */ 2523 if (!ch) { 2524 if (outbufptr) {*outbufptr++ = L'\0';} 2525 (*to_left)--; 2526 2527 continue; 2528 } 2529 2530 /* convert */ 2531 if (isleftside(ch)) { 2532 glyph_index = ch; 2533 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GL"); 2534 } else { 2535 glyph_index = ch & GL; 2536 codeset = _XlcGetCodeSetFromName(lcd, "ISO8859-1:GR"); 2537 } 2538 2539 if (!codeset) { 2540 unconv_num++; 2541 continue; 2542 } 2543 2544 gi_to_wc(lcd, glyph_index, codeset, &wc); 2545 if (outbufptr) {*outbufptr++ = wc;} 2546 (*to_left)--; 2547 2548 } /* end of while */ 2549 2550 *from = (XPointer) ((const char *) *from + from_size); 2551 *from_left = 0; 2552 *to = (XPointer) outbufptr; 2553 2554 return unconv_num; 2555} 2556 2557static int 2558stdc_strtowcs( 2559 XlcConv conv, 2560 XPointer *from, 2561 int *from_left, 2562 XPointer *to, 2563 int *to_left, 2564 XPointer *args, 2565 int num_args) 2566{ 2567 XPointer buf = Xmalloc((*from_left) * MB_CUR_MAX); 2568 char *buf_ptr1 = buf; 2569 int buf_left1 = (*from_left) * MB_CUR_MAX; 2570 char *buf_ptr2 = buf_ptr1; 2571 int buf_left2; 2572 int unconv_num1 = 0, unconv_num2 = 0; 2573 2574 unconv_num1 = strtombs(conv, 2575 from, from_left, &buf_ptr1, &buf_left1, args, num_args); 2576 if (unconv_num1 < 0) 2577 goto ret; 2578 2579 buf_left2 = buf_ptr1 - buf_ptr2; 2580 2581 unconv_num2 = stdc_mbstowcs(conv, 2582 &buf_ptr2, &buf_left2, to, to_left, args, num_args); 2583 if (unconv_num2 < 0) 2584 goto ret; 2585 2586ret: 2587 Xfree(buf); 2588 2589 return (unconv_num1 + unconv_num2); 2590} 2591 2592/* -------------------------------------------------------------------------- */ 2593/* Close */ 2594/* -------------------------------------------------------------------------- */ 2595 2596static void 2597close_converter( 2598 XlcConv conv) 2599{ 2600 Xfree(conv->state); 2601 Xfree(conv->methods); 2602 Xfree(conv); 2603} 2604 2605/* -------------------------------------------------------------------------- */ 2606/* Open */ 2607/* -------------------------------------------------------------------------- */ 2608 2609static XlcConv 2610create_conv( 2611 XLCd lcd, 2612 XlcConvMethods methods) 2613{ 2614 XlcConv conv; 2615 State state; 2616 2617 conv = Xcalloc(1, sizeof(XlcConvRec)); 2618 if (conv == NULL) 2619 return (XlcConv) NULL; 2620 2621 conv->methods = Xmalloc(sizeof(XlcConvMethodsRec)); 2622 if (conv->methods == NULL) 2623 goto err; 2624 *conv->methods = *methods; 2625 conv->methods->reset = init_state; 2626 2627 conv->state = Xcalloc(1, sizeof(StateRec)); 2628 if (conv->state == NULL) 2629 goto err; 2630 2631 state = (State) conv->state; 2632 state->lcd = lcd; 2633 2634 _XlcResetConverter(conv); 2635 2636 return conv; 2637 2638err: 2639 close_converter(conv); 2640 2641 return (XlcConv) NULL; 2642} 2643 2644static XlcConvMethodsRec mbstocts_methods = { 2645 close_converter, 2646 mbstocts, 2647 NULL 2648}; 2649 2650static XlcConv 2651open_mbstocts( 2652 XLCd from_lcd, 2653 const char *from_type, 2654 XLCd to_lcd, 2655 const char *to_type) 2656{ 2657 return create_conv(from_lcd, &mbstocts_methods); 2658} 2659 2660static XlcConvMethodsRec mbstostr_methods = { 2661 close_converter, 2662 mbstostr, 2663 NULL 2664}; 2665 2666static XlcConv 2667open_mbstostr( 2668 XLCd from_lcd, 2669 const char *from_type, 2670 XLCd to_lcd, 2671 const char *to_type) 2672{ 2673 return create_conv(from_lcd, &mbstostr_methods); 2674} 2675 2676static XlcConvMethodsRec mbstocs_methods = { 2677 close_converter, 2678 mbstocs, 2679 NULL 2680}; 2681 2682static XlcConv 2683open_mbstocs( 2684 XLCd from_lcd, 2685 const char *from_type, 2686 XLCd to_lcd, 2687 const char *to_type) 2688{ 2689 return create_conv(from_lcd, &mbstocs_methods); 2690} 2691 2692static XlcConvMethodsRec mbtocs_methods = { 2693 close_converter, 2694 mbtocs, 2695 NULL 2696}; 2697 2698static XlcConv 2699open_mbtocs( 2700 XLCd from_lcd, 2701 const char *from_type, 2702 XLCd to_lcd, 2703 const char *to_type) 2704{ 2705 return create_conv(from_lcd, &mbtocs_methods); 2706} 2707 2708static XlcConvMethodsRec ctstombs_methods = { 2709 close_converter, 2710 ctstombs, 2711 NULL 2712}; 2713 2714static XlcConv 2715open_ctstombs( 2716 XLCd from_lcd, 2717 const char *from_type, 2718 XLCd to_lcd, 2719 const char *to_type) 2720{ 2721 return create_conv(from_lcd, &ctstombs_methods); 2722} 2723 2724static XlcConvMethodsRec cstombs_methods = { 2725 close_converter, 2726 cstombs, 2727 NULL 2728}; 2729 2730static XlcConv 2731open_cstombs( 2732 XLCd from_lcd, 2733 const char *from_type, 2734 XLCd to_lcd, 2735 const char *to_type) 2736{ 2737 return create_conv(from_lcd, &cstombs_methods); 2738} 2739 2740static XlcConvMethodsRec strtombs_methods = { 2741 close_converter, 2742 strtombs, 2743 NULL 2744}; 2745 2746static XlcConv 2747open_strtombs( 2748 XLCd from_lcd, 2749 const char *from_type, 2750 XLCd to_lcd, 2751 const char *to_type) 2752{ 2753 return create_conv(from_lcd, &strtombs_methods); 2754} 2755 2756#ifdef STDCVT 2757 2758static XlcConvMethodsRec stdc_mbstowcs_methods = { 2759 close_converter, 2760 stdc_mbstowcs, 2761 NULL 2762}; 2763 2764static XlcConv 2765open_stdc_mbstowcs( 2766 XLCd from_lcd, 2767 const char *from_type, 2768 XLCd to_lcd, 2769 const char *to_type) 2770{ 2771 return create_conv(from_lcd, &stdc_mbstowcs_methods); 2772} 2773 2774static XlcConvMethodsRec stdc_wcstombs_methods = { 2775 close_converter, 2776 stdc_wcstombs, 2777 NULL 2778}; 2779 2780static XlcConv 2781open_stdc_wcstombs( 2782 XLCd from_lcd, 2783 const char *from_type, 2784 XLCd to_lcd, 2785 const char *to_type) 2786{ 2787 return create_conv(from_lcd, &stdc_wcstombs_methods); 2788} 2789 2790static XlcConvMethodsRec stdc_wcstocts_methods = { 2791 close_converter, 2792 stdc_wcstocts, 2793 NULL 2794}; 2795 2796static XlcConv 2797open_stdc_wcstocts( 2798 XLCd from_lcd, 2799 const char *from_type, 2800 XLCd to_lcd, 2801 const char *to_type) 2802{ 2803 return create_conv(from_lcd, &stdc_wcstocts_methods); 2804} 2805 2806static XlcConvMethodsRec stdc_wcstostr_methods = { 2807 close_converter, 2808 stdc_wcstostr, 2809 NULL 2810}; 2811 2812static XlcConv 2813open_stdc_wcstostr( 2814 XLCd from_lcd, 2815 const char *from_type, 2816 XLCd to_lcd, 2817 const char *to_type) 2818{ 2819 return create_conv(from_lcd, &stdc_wcstostr_methods); 2820} 2821 2822static XlcConvMethodsRec stdc_wcstocs_methods = { 2823 close_converter, 2824 stdc_wcstocs, 2825 NULL 2826}; 2827 2828static XlcConv 2829open_stdc_wcstocs( 2830 XLCd from_lcd, 2831 const char *from_type, 2832 XLCd to_lcd, 2833 const char *to_type) 2834{ 2835 return create_conv(from_lcd, &stdc_wcstocs_methods); 2836} 2837 2838static XlcConvMethodsRec stdc_wctocs_methods = { 2839 close_converter, 2840 stdc_wctocs, 2841 NULL 2842}; 2843 2844static XlcConv 2845open_stdc_wctocs( 2846 XLCd from_lcd, 2847 const char *from_type, 2848 XLCd to_lcd, 2849 const char *to_type) 2850{ 2851 return create_conv(from_lcd, &stdc_wctocs_methods); 2852} 2853 2854static XlcConvMethodsRec stdc_ctstowcs_methods = { 2855 close_converter, 2856 stdc_ctstowcs, 2857 NULL 2858}; 2859 2860static XlcConv 2861open_stdc_ctstowcs( 2862 XLCd from_lcd, 2863 const char *from_type, 2864 XLCd to_lcd, 2865 const char *to_type) 2866{ 2867 return create_conv(from_lcd, &stdc_ctstowcs_methods); 2868} 2869 2870static XlcConvMethodsRec stdc_cstowcs_methods = { 2871 close_converter, 2872 stdc_cstowcs, 2873 NULL 2874}; 2875 2876static XlcConv 2877open_stdc_cstowcs( 2878 XLCd from_lcd, 2879 const char *from_type, 2880 XLCd to_lcd, 2881 const char *to_type) 2882{ 2883 return create_conv(from_lcd, &stdc_cstowcs_methods); 2884} 2885 2886static XlcConvMethodsRec stdc_strtowcs_methods = { 2887 close_converter, 2888 stdc_strtowcs, 2889 NULL 2890}; 2891 2892static XlcConv 2893open_stdc_strtowcs( 2894 XLCd from_lcd, 2895 const char *from_type, 2896 XLCd to_lcd, 2897 const char *to_type) 2898{ 2899 return create_conv(from_lcd, &stdc_strtowcs_methods); 2900} 2901 2902#endif /* STDCVT */ 2903 2904static XlcConvMethodsRec mbstowcs_methods = { 2905 close_converter, 2906 mbstowcs_org, 2907 NULL 2908}; 2909 2910static XlcConv 2911open_mbstowcs( 2912 XLCd from_lcd, 2913 const char *from_type, 2914 XLCd to_lcd, 2915 const char *to_type) 2916{ 2917 return create_conv(from_lcd, &mbstowcs_methods); 2918} 2919 2920static XlcConvMethodsRec wcstombs_methods = { 2921 close_converter, 2922 wcstombs_org, 2923 NULL 2924}; 2925 2926static XlcConv 2927open_wcstombs( 2928 XLCd from_lcd, 2929 const char *from_type, 2930 XLCd to_lcd, 2931 const char *to_type) 2932{ 2933 return create_conv(from_lcd, &wcstombs_methods); 2934} 2935 2936static XlcConvMethodsRec wcstocts_methods = { 2937 close_converter, 2938 wcstocts, 2939 NULL 2940}; 2941 2942static XlcConv 2943open_wcstocts( 2944 XLCd from_lcd, 2945 const char *from_type, 2946 XLCd to_lcd, 2947 const char *to_type) 2948{ 2949 return create_conv(from_lcd, &wcstocts_methods); 2950} 2951 2952static XlcConvMethodsRec wcstostr_methods = { 2953 close_converter, 2954 wcstostr, 2955 NULL 2956}; 2957 2958static XlcConv 2959open_wcstostr( 2960 XLCd from_lcd, 2961 const char *from_type, 2962 XLCd to_lcd, 2963 const char *to_type) 2964{ 2965 return create_conv(from_lcd, &wcstostr_methods); 2966} 2967 2968static XlcConvMethodsRec wcstocs_methods = { 2969 close_converter, 2970 wcstocs, 2971 NULL 2972}; 2973 2974static XlcConv 2975open_wcstocs( 2976 XLCd from_lcd, 2977 const char *from_type, 2978 XLCd to_lcd, 2979 const char *to_type) 2980{ 2981 return create_conv(from_lcd, &wcstocs_methods); 2982} 2983 2984static XlcConvMethodsRec wctocs_methods = { 2985 close_converter, 2986 wctocs, 2987 NULL 2988}; 2989 2990static XlcConv 2991open_wctocs( 2992 XLCd from_lcd, 2993 const char *from_type, 2994 XLCd to_lcd, 2995 const char *to_type) 2996{ 2997 return create_conv(from_lcd, &wctocs_methods); 2998} 2999 3000static XlcConvMethodsRec ctstowcs_methods = { 3001 close_converter, 3002 ctstowcs, 3003 NULL 3004}; 3005 3006static XlcConv 3007open_ctstowcs( 3008 XLCd from_lcd, 3009 const char *from_type, 3010 XLCd to_lcd, 3011 const char *to_type) 3012{ 3013 return create_conv(from_lcd, &ctstowcs_methods); 3014} 3015 3016static XlcConvMethodsRec cstowcs_methods = { 3017 close_converter, 3018 cstowcs, 3019 NULL 3020}; 3021 3022static XlcConv 3023open_cstowcs( 3024 XLCd from_lcd, 3025 const char *from_type, 3026 XLCd to_lcd, 3027 const char *to_type) 3028{ 3029 return create_conv(from_lcd, &cstowcs_methods); 3030} 3031 3032static XlcConvMethodsRec strtowcs_methods = { 3033 close_converter, 3034 strtowcs, 3035 NULL 3036}; 3037 3038static XlcConv 3039open_strtowcs( 3040 XLCd from_lcd, 3041 const char *from_type, 3042 XLCd to_lcd, 3043 const char *to_type) 3044{ 3045 return create_conv(from_lcd, &strtowcs_methods); 3046} 3047 3048/* -------------------------------------------------------------------------- */ 3049/* Loader */ 3050/* -------------------------------------------------------------------------- */ 3051 3052XLCd 3053_XlcGenericLoader( 3054 const char *name) 3055{ 3056 XLCd lcd; 3057#ifdef STDCVT 3058 XLCdGenericPart *gen; 3059#endif 3060 3061 lcd = _XlcCreateLC(name, _XlcGenericMethods); 3062 3063 if (lcd == NULL) 3064 return lcd; 3065 3066 default_GL_charset = _XlcGetCharSet("ISO8859-1:GL"); 3067 default_GR_charset = _XlcGetCharSet("ISO8859-1:GR"); 3068 3069 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCompoundText, open_mbstocts); 3070 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNString, open_mbstostr); 3071 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNCharSet, open_mbstocs); 3072 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNChar, open_mbtocs); 3073 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNMultiByte, open_ctstombs); 3074 _XlcSetConverter(lcd, XlcNString, lcd, XlcNMultiByte, open_strtombs); 3075 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNMultiByte, open_cstombs); 3076 3077#ifdef STDCVT 3078 gen = XLC_GENERIC_PART(lcd); 3079 3080 if (gen->use_stdc_env != True) { 3081#endif 3082 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_mbstowcs); 3083 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_wcstombs); 3084 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_wcstocts); 3085 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_wcstostr); 3086 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_wcstocs); 3087 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_wctocs); 3088 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_ctstowcs); 3089 _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_strtowcs); 3090 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_cstowcs); 3091#ifdef STDCVT 3092 } 3093#endif 3094 3095#ifdef STDCVT 3096 if (gen->use_stdc_env == True) { 3097 _XlcSetConverter(lcd, XlcNMultiByte, lcd, XlcNWideChar, open_stdc_mbstowcs); 3098 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNMultiByte, open_stdc_wcstombs); 3099 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCompoundText, open_stdc_wcstocts); 3100 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNString, open_stdc_wcstostr); 3101 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNCharSet, open_stdc_wcstocs); 3102 _XlcSetConverter(lcd, XlcNWideChar, lcd, XlcNChar, open_stdc_wctocs); 3103 _XlcSetConverter(lcd, XlcNCompoundText, lcd, XlcNWideChar, open_stdc_ctstowcs); 3104 _XlcSetConverter(lcd, XlcNString, lcd, XlcNWideChar, open_stdc_strtowcs); 3105 _XlcSetConverter(lcd, XlcNCharSet, lcd, XlcNWideChar, open_stdc_cstowcs); 3106 } 3107#endif 3108 3109 _XlcAddUtf8Converters(lcd); 3110 3111 return lcd; 3112} 3113