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