| 562 | } |
| 563 | |
| 564 | char *reencode_string_len(const char *in, size_t insz, |
| 565 | const char *out_encoding, const char *in_encoding, |
| 566 | size_t *outsz) |
| 567 | { |
| 568 | iconv_t conv; |
| 569 | char *out; |
| 570 | const char *bom_str = NULL; |
| 571 | size_t bom_len = 0; |
| 572 | |
| 573 | if (!in_encoding) |
| 574 | return NULL; |
| 575 | |
| 576 | /* UTF-16LE-BOM is the same as UTF-16 for reading */ |
| 577 | if (same_utf_encoding("UTF-16LE-BOM", in_encoding)) |
| 578 | in_encoding = "UTF-16"; |
| 579 | |
| 580 | /* |
| 581 | * For writing, UTF-16 iconv typically creates "UTF-16BE-BOM" |
| 582 | * Some users under Windows want the little endian version |
| 583 | * |
| 584 | * We handle UTF-16 and UTF-32 ourselves only if the platform does not |
| 585 | * provide a BOM (which we require), since we want to match the behavior |
| 586 | * of the system tools and libc as much as possible. |
| 587 | */ |
| 588 | if (same_utf_encoding("UTF-16LE-BOM", out_encoding)) { |
| 589 | bom_str = utf16_le_bom; |
| 590 | bom_len = sizeof(utf16_le_bom); |
| 591 | out_encoding = "UTF-16LE"; |
| 592 | } else if (same_utf_encoding("UTF-16BE-BOM", out_encoding)) { |
| 593 | bom_str = utf16_be_bom; |
| 594 | bom_len = sizeof(utf16_be_bom); |
| 595 | out_encoding = "UTF-16BE"; |
| 596 | #ifdef ICONV_OMITS_BOM |
| 597 | } else if (same_utf_encoding("UTF-16", out_encoding)) { |
| 598 | bom_str = utf16_be_bom; |
| 599 | bom_len = sizeof(utf16_be_bom); |
| 600 | out_encoding = "UTF-16BE"; |
| 601 | } else if (same_utf_encoding("UTF-32", out_encoding)) { |
| 602 | bom_str = utf32_be_bom; |
| 603 | bom_len = sizeof(utf32_be_bom); |
| 604 | out_encoding = "UTF-32BE"; |
| 605 | #endif |
| 606 | } |
| 607 | |
| 608 | conv = iconv_open(out_encoding, in_encoding); |
| 609 | if (conv == (iconv_t) -1) { |
| 610 | in_encoding = fallback_encoding(in_encoding); |
| 611 | out_encoding = fallback_encoding(out_encoding); |
| 612 | |
| 613 | conv = iconv_open(out_encoding, in_encoding); |
| 614 | if (conv == (iconv_t) -1) |
| 615 | return NULL; |
| 616 | } |
| 617 | out = reencode_string_iconv(in, insz, conv, bom_len, outsz); |
| 618 | iconv_close(conv); |
| 619 | if (out && bom_str && bom_len) |
| 620 | memcpy(out, bom_str, bom_len); |
| 621 | return out; |
no test coverage detected