1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 1995, by Sun Microsystems, Inc. 23 * All rights reserved. 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <strings.h> 29 #include <errno.h> 30 #ifdef DEBUG 31 #include <sys/fcntl.h> 32 #include <sys/stat.h> 33 #endif 34 #include <cns11643_big5.h> /* CNS 11643 to Big-5 mapping table */ 35 #include <big5_gb18030.h> /* Big-5 to GBK mapping table */ 36 37 #define MSB 0x80 /* most significant bit */ 38 #define MBYTE 0x8e /* multi-byte (4 byte character) */ 39 #define PMASK 0xa0 /* plane number mask */ 40 #define ONEBYTE 0xff /* right most byte */ 41 #define MSB_OFF 0x7f /* mask off MBS */ 42 43 #define SI 0x0f /* shift in */ 44 #define SO 0x0e /* shift out */ 45 #define ESC 0x1b /* escape */ 46 #define SS2 0x4e /* SS2 shift out */ 47 #define SS3 0x4f /* SS3 shift out */ 48 #define NON_ID_CHAR_BYTE1 0xA1 /* non-identified character */ 49 #define NON_ID_CHAR_BYTE2 0xF5 /* non-identified character */ 50 51 typedef struct _icv_state { 52 char _buf[10]; 53 size_t _bufcont; 54 char _keepc[4]; /* maximum # byte of CNS11643 code */ 55 short _gstate; /* state machine id */ 56 short _istate; /* state for shift in/out */ 57 int _plane; /* plane number for Chinese character */ 58 int _last_plane; /* last charactor's plane # */ 59 int _errno; /* internal errno */ 60 } _iconv_st; 61 62 enum _GSTATE { G0, G1, G2, G3, G4, G5, G6, G7, G8, G9, \ 63 G10,G11,G12,G13,G14,G15,G16,G17,G18,G19, \ 64 G20,G21,G22,G23,G24,G25,G26,G27,G28,G29 }; 65 66 enum _ISTATE { IN, OUT }; 67 68 69 int iso_gb_to_gbk(_iconv_st * st, char* buf, size_t buflen); 70 int iso_to_big5_to_gbk(_iconv_st * st, char* buf, size_t buflen); 71 int binsearch(unsigned long x, table_t v[], int n); 72 int binsearch_big5_gbk(unsigned int big5code); 73 int flush_buf(_iconv_st * st, char ** outbuf, size_t * outbytesleft); 74 75 int flush_buf(_iconv_st * st, char ** outbuf, size_t * outbytesleft) { 76 if (!st->_bufcont) 77 return 0; 78 if (st->_bufcont > *outbytesleft) { 79 st->_errno = E2BIG; 80 return -1; 81 } 82 if (st->_istate != IN) { 83 st->_errno = EILSEQ; 84 return -1; 85 } 86 strncpy(st->_buf, *outbuf, st->_bufcont); 87 (*outbuf)+=(st->_bufcont); 88 (*outbytesleft)-=(st->_bufcont); 89 st->_bufcont = 0; 90 return st->_bufcont; 91 } 92 93 /* 94 * Open; called from iconv_open() 95 */ 96 void * 97 _icv_open() 98 { 99 _iconv_st *st; 100 101 if ((st = (_iconv_st *)malloc(sizeof(_iconv_st))) == NULL) { 102 errno = ENOMEM; 103 return ((void *) -1); 104 } 105 106 st->_gstate = G0; 107 st->_istate = IN; 108 st->_last_plane = st->_plane = -1; 109 st->_errno = 0; 110 st->_bufcont = 0; 111 112 return ((void *) st); 113 } 114 115 /* 116 * Close; called from iconv_close() 117 */ 118 void 119 _icv_close(_iconv_st *st) 120 { 121 if (st == NULL) 122 errno = EBADF; 123 else 124 free(st); 125 } 126 127 /* 128 * Actual conversion; called from iconv() 129 */ 130 /*========================================================================= 131 * 132 * State Machine for interpreting ISO 2022-7 code 133 * 134 *========================================================================= 135 * 136 * plane 2 - 16 137 * +---------->-------+ 138 * plane ^ | 139 * ESC $ ) number SO | plane 1 v 140 * +-> G0 ----> G1 ---> G2 ---> G3 ------> G4 --> G5 -------> G6 G7 141 * | | ascii | ascii | ascii | ascii | SI | | | | 142 * +----------------------------+ <-----+------+ +------<---+------+ 143 * ^ | 144 * | ascii v 145 * +---------<-------------<---------+ 146 * 147 *=========================================================================*/ 148 size_t _icv_iconv(_iconv_st *st, \ 149 char **inbuf, size_t *inbytesleft, \ 150 char **outbuf, size_t *outbytesleft) { 151 int n; 152 char c; 153 154 if (st == NULL) { 155 errno = EBADF; 156 return ((size_t) -1); 157 } 158 159 if (inbuf == NULL || *inbuf == NULL) { /* Reset request. */ 160 st->_gstate = G0; 161 st->_istate = IN; 162 st->_errno = 0; 163 st->_plane = st->_last_plane = -1; 164 return ((size_t) 0); 165 } 166 167 errno = st->_errno = 0; /* reset internal and external errno */ 168 169 /* a state machine for interpreting ISO 2022-7 code */ 170 while (*inbytesleft > 0 && *outbytesleft > 0) { 171 switch (st->_gstate) { 172 case G0: /* assuming ASCII in the beginning */ 173 if (**inbuf == ESC) { 174 st->_gstate = G1; 175 st->_buf[st->_bufcont++] = ESC; 176 } else { /* real ASCII */ 177 **outbuf = **inbuf; 178 (*outbuf)++; 179 (*outbytesleft)--; 180 } 181 break; 182 case G1: /* got ESC, expecting $ */ 183 if (**inbuf == '$') { 184 st->_gstate = G2; 185 st->_buf[st->_bufcont++] = '$'; 186 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 187 errno = st->_errno; 188 return (size_t)-1; 189 } else { 190 st->_gstate = G0; 191 st->_errno = 0; 192 st->_istate = IN; 193 continue; /* don't advance inbuf */ 194 } 195 break; 196 case G2: /* got $, expecting ) * or + */ 197 if (**inbuf == ')') { 198 st->_gstate = G3; 199 } else if (**inbuf == '*') { 200 st->_gstate = G12; 201 st->_plane = 2; 202 } else if (**inbuf == '+') { 203 st->_gstate = G19; 204 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 205 errno = st->_errno; 206 return (size_t)-1; 207 } else { 208 st->_gstate = G0; 209 st->_errno = 0; 210 st->_istate = IN; 211 continue; /* don't advance inbuf */ 212 } 213 st->_buf[st->_bufcont++] = **inbuf; 214 break; 215 case G3: /* got ) expecting A,G,H */ 216 /* H is for the bug of and zh_TW.BIG5 */ 217 if (**inbuf == 'A') { 218 st->_plane = 0; 219 st->_gstate = G4; 220 } else if (**inbuf == 'G') { 221 st->_plane = 1; 222 st->_gstate = G8; 223 } else if (**inbuf == 'H') { 224 st->_plane = 2; 225 st->_gstate = G8; 226 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 227 errno = st->_errno; 228 return (size_t)-1; 229 } else { 230 st->_gstate = G0; 231 st->_errno = 0; 232 st->_istate = IN; 233 continue; 234 } 235 st->_buf[st->_bufcont++] = **inbuf; 236 break; 237 case G4: /* ESC $ ) A got, and SO is expected */ 238 if (**inbuf == SO) { 239 st->_gstate = G5; 240 st->_istate = OUT; 241 st->_bufcont = 0; 242 st->_last_plane = st->_plane; 243 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 244 errno = st->_errno; 245 return (size_t)-1; 246 } else { 247 st->_gstate = G0; 248 st->_errno = 0; 249 st->_istate = IN; 250 st->_plane = st->_last_plane; 251 continue; 252 } 253 break; 254 case G5: /* SO (Shift Out) */ 255 if (**inbuf == SI) { 256 st->_istate = IN; 257 st->_gstate = G7; 258 st->_last_plane = st->_plane; 259 } else if (**inbuf == ESC) { 260 /* 261 && *((*inbuf) + 1) == '$') { 262 if (flush_buf(st, outbuf, outbytesleft) == -1) { 263 errno = st->_errno; 264 return (size_t)-1; 265 } 266 */ 267 st->_bufcont = 0; 268 st->_gstate = G0; 269 continue; 270 } else { /* Chinese Charactors */ 271 st->_keepc[0] = **inbuf; 272 st->_gstate = G6; 273 } 274 break; 275 case G6: /* GB2312: 2nd Chinese character */ 276 st->_keepc[1] = **inbuf; 277 n = iso_gb_to_gbk(st, *outbuf, *outbytesleft); 278 if (n > 0) { 279 (*outbuf) += n; 280 (*outbytesleft) -= n; 281 } else { 282 errno = st->_errno; 283 return (size_t)-1; 284 } 285 st->_gstate = G5; 286 break; 287 case G7: /* Shift in */ 288 if (**inbuf == SO) { 289 st->_gstate = G5; 290 st->_istate = OUT; 291 st->_last_plane = st->_plane; 292 st->_bufcont = 0; 293 } else if (**inbuf == ESC) { 294 /* 295 && *((*inbuf) + 1) == '$') { 296 */ 297 st->_gstate = G0; 298 continue; 299 } else { 300 **outbuf = **inbuf; 301 (*outbuf)++; 302 (*outbytesleft) --; 303 } 304 break; 305 case G8: /* BIG5: Chinese character */ 306 if (**inbuf == SO) { 307 st->_istate = OUT; 308 st->_gstate = G9; 309 st->_bufcont = 0; 310 st->_last_plane = st->_plane; 311 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 312 errno = st->_errno; 313 return (size_t)-1; 314 } else { 315 st->_gstate = G0; 316 st->_errno = 0; 317 st->_plane = st->_last_plane; 318 st->_istate = IN; 319 continue; 320 } 321 break; 322 case G9: 323 if (**inbuf == SI) { 324 st->_istate = IN; 325 st->_gstate = G11; 326 st->_last_plane = st->_plane; 327 } else if (**inbuf == ESC) { 328 /* 329 && *((*inbuf) + 1) == '$') { 330 */ 331 if (flush_buf(st, outbuf, outbytesleft) == -1) { 332 errno = st->_errno; 333 return (size_t)-1; 334 } 335 st->_gstate = G0; 336 continue; 337 } else { /* Chinese Charactor */ 338 st->_keepc[0] = **inbuf; 339 st->_gstate = G10; 340 } 341 break; 342 case G10: 343 st->_keepc[1] = **inbuf; 344 n = iso_to_big5_to_gbk(st, *outbuf, *outbytesleft); 345 if (n > 0) { 346 (*outbuf) += n; 347 (*outbytesleft) -= n; 348 } else { 349 errno = st->_errno; 350 return (size_t)-1; 351 } 352 st->_gstate = G9; 353 break; 354 case G11: 355 st->_bufcont = 0; 356 if (**inbuf == SO) { 357 st->_istate = OUT; 358 st->_gstate = G9; 359 } else if (**inbuf == ESC) { 360 /* 361 && *((*inbuf) + 1) == '$') { 362 */ 363 st->_gstate = G0; 364 continue; 365 } else { 366 **outbuf = **inbuf; 367 (*outbuf)++; 368 (*outbytesleft)--; 369 } 370 break; 371 case G12: 372 if (**inbuf == 'H') { 373 st->_buf[st->_bufcont++] = 'H'; 374 st->_gstate = G13; 375 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 376 errno = st->_errno; 377 return (size_t)-1; 378 } else { 379 st->_istate = IN; 380 st->_plane = st->_last_plane; 381 st->_gstate = G0; 382 continue; 383 } 384 break; 385 case G13: 386 if (**inbuf == ESC) { 387 st->_buf[st->_bufcont++] = **inbuf; 388 st->_gstate = G14; 389 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 390 errno = st->_errno; 391 return (size_t)-1; 392 } else { 393 st->_gstate = G0; 394 st->_istate = IN; 395 st->_plane = st->_last_plane; 396 continue; 397 } 398 break; 399 case G14: 400 if (**inbuf == SS2) { 401 st->_istate = OUT; 402 st->_gstate = G15; 403 st->_bufcont = 0; 404 st->_last_plane = st->_plane = 2; 405 } else if (**inbuf == '$') { 406 st->_bufcont --; 407 if (flush_buf(st, outbuf, outbytesleft) == -1) { 408 errno = st->_errno; 409 return (size_t)-1; 410 } else { 411 st->_gstate = G1; 412 st->_plane = st->_last_plane; 413 st->_istate = IN; 414 continue; 415 } 416 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 417 errno = st->_errno; 418 return (size_t)-1; 419 } else { 420 st->_gstate = G0; 421 st->_istate = IN; 422 st->_plane = st->_last_plane; 423 continue; 424 } 425 break; 426 case G15: 427 if (**inbuf == SI) { 428 st->_gstate = G16; 429 st->_istate = IN; 430 st->_last_plane = st->_plane; 431 } else if (**inbuf == ESC) { 432 /* 433 && *((*inbuf) + 1) == '$') { 434 */ 435 st->_bufcont = 0; 436 st->_gstate = G0; 437 continue; 438 } else { 439 st->_keepc[0] = **inbuf; 440 st->_gstate = G18; 441 } 442 break; 443 case G16: 444 if (**inbuf == ESC) { 445 st->_gstate = G17; 446 st->_buf[st->_bufcont++] = ESC; 447 } else { 448 **outbuf = **inbuf; 449 (*outbuf) ++; 450 (*outbytesleft) --; 451 st->_bufcont = 0; 452 } 453 break; 454 case G17: 455 if (**inbuf == '$') { 456 st->_gstate = G1; 457 st->_buf[st->_bufcont++] = '$'; 458 continue; 459 } else if (**inbuf == SS2) { 460 st->_bufcont = 0; 461 st->_gstate = G15; 462 st->_istate = OUT; 463 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 464 errno = st->_errno; 465 return (size_t)-1; 466 } else { 467 st->_gstate = G16; 468 st->_istate = IN; 469 } 470 break; 471 case G18: 472 st->_keepc[1] = **inbuf; 473 st->_gstate = G15; 474 if ((n = iso_to_big5_to_gbk(st, \ 475 *outbuf, \ 476 *outbytesleft)) > 0) { 477 (*outbuf)+=n; 478 (*outbytesleft)-=n; 479 } else { 480 errno = st->_errno; 481 return (size_t)-1; 482 } 483 break; 484 case G19: /* Plane #: 3 - 16 */ 485 c = **inbuf; 486 if (c == 'I' || \ 487 c == 'J' || \ 488 c == 'K' || \ 489 c == 'L' || \ 490 c == 'M' || \ 491 c == 'N' || \ 492 c == 'O' || \ 493 c == 'P' || \ 494 c == 'Q' || \ 495 c == 'R' || \ 496 c == 'S' || \ 497 c == 'T' || \ 498 c == 'U' || \ 499 c == 'V') { 500 st->_plane = c - 'I' + 3; 501 st->_gstate = G20; 502 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 503 errno = st->_errno; 504 return (size_t)-1; 505 } else { 506 st->_gstate = G0; 507 st->_errno = 0; 508 st->_istate = IN; 509 st->_plane = st->_last_plane; 510 continue; 511 } 512 st->_buf[st->_bufcont++] = c; 513 break; 514 case G20: 515 if (**inbuf == ESC) { 516 st->_buf[st->_bufcont++] = **inbuf; 517 st->_gstate = G21; 518 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 519 errno = st->_errno; 520 return (size_t)-1; 521 } else { 522 st->_gstate = G0; 523 st->_istate = IN; 524 st->_last_plane = st->_plane; 525 continue; 526 } 527 break; 528 case G21: 529 if (**inbuf == SS3) { 530 st->_istate = OUT; 531 st->_gstate = G22; 532 st->_bufcont = 0; 533 } else if (**inbuf == '$') { 534 st->_bufcont --; 535 if (flush_buf(st, outbuf, outbytesleft) == -1) { 536 errno = st->_errno; 537 return (size_t)-1; 538 } else { 539 st->_istate = IN; 540 st->_last_plane = st->_plane; 541 st->_gstate = G1; 542 continue; 543 } 544 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 545 errno = st->_errno; 546 return (size_t)-1; 547 } else { 548 st->_gstate = G0; 549 st->_istate = IN; 550 st->_last_plane = st->_plane; 551 continue; 552 } 553 break; 554 case G22: 555 if (**inbuf == SI) { 556 st->_istate = IN; 557 st->_gstate = G24; 558 st->_last_plane = st->_plane; 559 } else { 560 st->_keepc[0] = (char)MBYTE; 561 st->_keepc[1] = (char)(PMASK + st->_plane); 562 st->_keepc[2] = **inbuf; 563 st->_gstate = G23; 564 } 565 break; 566 case G23: 567 st->_keepc[3] = **inbuf; 568 if ((n = iso_to_big5_to_gbk(st, \ 569 *outbuf, \ 570 *outbytesleft)) > 0) { 571 (*outbuf)+=n; 572 (*outbytesleft-=n); 573 } else { 574 st->_errno = errno; 575 return (size_t)-1; 576 } 577 st->_gstate = G22; 578 break; 579 case G24: 580 if (**inbuf == ESC) { 581 st->_gstate = G25; 582 st->_buf[st->_bufcont++] = ESC; 583 } else { 584 **outbuf = **inbuf; 585 (*outbuf)++; 586 (*outbytesleft)--; 587 st->_bufcont = 0; 588 } 589 break; 590 case G25: 591 if (**inbuf == '$') { 592 st->_gstate = G1; 593 continue; 594 } else if (**inbuf == SS3) { 595 st->_gstate = G22; 596 st->_bufcont = 0; 597 st->_istate = OUT; 598 } else if (flush_buf(st, outbuf, outbytesleft) == -1) { 599 errno = st->_errno; 600 return (size_t)-1; 601 } else { 602 st->_gstate = G24; 603 st->_istate = IN; 604 } 605 break; 606 default: /* should never come here */ 607 st->_errno = errno = EILSEQ; 608 st->_gstate = G0; /* reset state */ 609 break; 610 } /* end of switch */ 611 612 (*inbuf)++; 613 (*inbytesleft)--; 614 615 if (st->_errno) { 616 break; 617 } 618 if (errno) 619 return((size_t)(-1)); 620 } 621 622 if (*inbytesleft > 0 && *outbytesleft == 0) { 623 errno = E2BIG; 624 return((size_t)(-1)); 625 } 626 return (size_t)(*inbytesleft); 627 } 628 629 int iso_gb_to_gbk(_iconv_st * st, char* buf, size_t buflen) { 630 if ( buflen < 2 ) { 631 st->_errno = E2BIG; 632 return -1; 633 } 634 *buf = st->_keepc[0] | MSB; 635 *(buf+1) = st->_keepc[1] | MSB; 636 return 2; 637 } 638 639 /* 640 * ISO 2022-7 code --> Big-5 code 641 * Return: > 0 - converted with enough space in output buffer 642 * = 0 - no space in outbuf 643 */ 644 int iso_to_big5_to_gbk(_iconv_st * st, char* buf, size_t buflen) { 645 char cns_str[3], c1, c2; 646 unsigned long cns_val; /* MSB mask off CNS 11643 value */ 647 int unidx; /* binary search index */ 648 unsigned long big5_val, val; /* Big-5 code */ 649 int idx; 650 651 if (st->_plane == 1) { 652 cns_str[0] = st->_keepc[0] & MSB_OFF; 653 cns_str[1] = st->_keepc[1] & MSB_OFF; 654 } else { 655 cns_str[0] = st->_keepc[0] & MSB_OFF; 656 cns_str[1] = st->_keepc[1] & MSB_OFF; 657 } 658 cns_val = (cns_str[0] << 8) + cns_str[1]; 659 660 if (buflen < 2) { 661 errno = E2BIG; 662 return(0); 663 } 664 665 switch (st->_plane) { 666 case 1: 667 unidx = binsearch(cns_val, cns_big5_tab1, MAX_CNS1_NUM); 668 if (unidx >= 0) 669 big5_val = cns_big5_tab1[unidx].value; 670 break; 671 case 2: 672 unidx = binsearch(cns_val, cns_big5_tab2, MAX_CNS2_NUM); 673 if (unidx >= 0) 674 big5_val = cns_big5_tab2[unidx].value; 675 break; 676 default: 677 unidx = -1; /* no mapping from CNS to Big-5 out of plane 1&2 */ 678 break; 679 } 680 681 682 if (unidx < 0) { /* no match from CNS to Big-5 */ 683 *buf = NON_ID_CHAR_BYTE1; 684 *(buf+1) = NON_ID_CHAR_BYTE2; 685 } else { 686 val = big5_val & 0xffff; 687 *buf = c1 = (char) ((val & 0xff00) >> 8); 688 *(buf+1) = c2 = (char) (val & 0xff); 689 } 690 691 692 if (unidx < 0) { 693 return 2; 694 } else { 695 idx = binsearch_big5_gbk((((*buf) & ONEBYTE) << 8) | ((*(buf+1)) & ONEBYTE)); 696 if (idx < 0) { 697 *buf = NON_ID_CHAR_BYTE1; 698 *(buf+1) = NON_ID_CHAR_BYTE2; 699 } else { 700 *buf = (big5_gbk_tab[idx].value >> 8) & ONEBYTE; 701 *(buf+1) = big5_gbk_tab[idx].value & ONEBYTE; 702 } 703 } 704 705 return(2); 706 } 707 708 /* binsearch: find x in v[0] <= v[1] <= ... <= v[n-1] */ 709 int binsearch(unsigned long x, table_t v[], int n) 710 { 711 int low, high, mid; 712 713 low = 0; 714 high = n - 1; 715 while (low <= high) { 716 mid = (low + high) / 2; 717 if (x < v[mid].key) 718 high = mid - 1; 719 else if (x > v[mid].key) 720 low = mid + 1; 721 else /* found match */ 722 return mid; 723 } 724 return (-1); /* no match */ 725 } 726 727 int binsearch_big5_gbk(unsigned int big5code) 728 { 729 int low, high, mid; 730 731 low = 0; 732 high = BIG5MAX - 1; 733 while (low <= high) { 734 mid = (low + high) / 2; 735 if (big5code < big5_gbk_tab[mid].key) 736 high = mid - 1; 737 else if (big5code > big5_gbk_tab[mid].key) 738 low = mid + 1; 739 else /* found match */ 740 return mid; 741 } 742 return (-1); /* no match */ 743 } 744 745 #ifdef DEBUG 746 main(int argc, char ** argv) { 747 char *inbuf, *outbuf, *in_tmp, *out_tmp; 748 size_t inbytesleft, outbytesleft; 749 int fd; 750 int i; 751 struct stat s; 752 _iconv_st * st; 753 if (argc < 2) { 754 fprintf(stderr, "Usage: %s input\n", argv[0]); 755 exit(-1); 756 } 757 if ((fd = open(argv[1], O_RDONLY)) == -1) { 758 perror("open"); 759 exit(-2); 760 } 761 if (fstat(fd, &s) == -1) { 762 perror("stat"); 763 exit(-3); 764 } 765 inbytesleft = outbytesleft = s.st_size; 766 in_tmp = inbuf = (char *)malloc(inbytesleft); 767 out_tmp = outbuf = (char *)malloc(outbytesleft); 768 if (!inbuf || !outbuf) { 769 perror("malloc"); 770 exit(-1); 771 } 772 if (read(fd, inbuf, inbytesleft) != inbytesleft) { 773 perror("read"); 774 exit(-4); 775 } 776 for (i = 0; i < inbytesleft; i++) 777 fprintf(stderr, "%x\t", *(inbuf+i)); 778 fprintf(stderr, "\n"); 779 st = (_iconv_st *)_icv_open(); 780 if (st == (_iconv_st *) -1) { 781 perror("_icv_open"); 782 exit(-1); 783 } 784 if (_icv_iconv(st, \ 785 &inbuf, &inbytesleft, \ 786 &outbuf, &outbytesleft) == -1) { 787 perror("icv_iconv"); 788 fprintf(stderr, "\ninbytesleft = %d\n", inbytesleft); 789 exit(-2); 790 } 791 if (write(1, out_tmp, s.st_size - outbytesleft) == -1) { 792 perror("write"); 793 exit(-1); 794 } 795 free(in_tmp); 796 free(out_tmp); 797 close(fd); 798 _icv_close(st); 799 } 800 #endif 801