| 566 | /* --------------------------------------------------------------------- */ |
| 567 | |
| 568 | ConversionResult ConvertUTF8toUTF16 ( |
| 569 | const UTF8** sourceStart, const UTF8* sourceEnd, |
| 570 | UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { |
| 571 | ConversionResult result = conversionOK; |
| 572 | const UTF8* source = *sourceStart; |
| 573 | UTF16* target = *targetStart; |
| 574 | while (source < sourceEnd) { |
| 575 | UTF32 ch = 0; |
| 576 | unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; |
| 577 | if (extraBytesToRead >= sourceEnd - source) { |
| 578 | result = sourceExhausted; break; |
| 579 | } |
| 580 | /* Do this check whether lenient or strict */ |
| 581 | if (!isLegalUTF8(source, extraBytesToRead+1)) { |
| 582 | result = sourceIllegal; |
| 583 | break; |
| 584 | } |
| 585 | /* |
| 586 | * The cases all fall through. See "Note A" below. |
| 587 | */ |
| 588 | switch (extraBytesToRead) { |
| 589 | case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ |
| 590 | case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ |
| 591 | case 3: ch += *source++; ch <<= 6; |
| 592 | case 2: ch += *source++; ch <<= 6; |
| 593 | case 1: ch += *source++; ch <<= 6; |
| 594 | case 0: ch += *source++; |
| 595 | } |
| 596 | ch -= offsetsFromUTF8[extraBytesToRead]; |
| 597 | |
| 598 | if (target >= targetEnd) { |
| 599 | source -= (extraBytesToRead+1); /* Back up source pointer! */ |
| 600 | result = targetExhausted; break; |
| 601 | } |
| 602 | if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ |
| 603 | /* UTF-16 surrogate values are illegal in UTF-32 */ |
| 604 | if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { |
| 605 | if (flags == strictConversion) { |
| 606 | source -= (extraBytesToRead+1); /* return to the illegal value itself */ |
| 607 | result = sourceIllegal; |
| 608 | break; |
| 609 | } else { |
| 610 | *target++ = UNI_REPLACEMENT_CHAR; |
| 611 | } |
| 612 | } else { |
| 613 | *target++ = (UTF16)ch; /* normal case */ |
| 614 | } |
| 615 | } else if (ch > UNI_MAX_UTF16) { |
| 616 | if (flags == strictConversion) { |
| 617 | result = sourceIllegal; |
| 618 | source -= (extraBytesToRead+1); /* return to the start */ |
| 619 | break; /* Bail out; shouldn't continue */ |
| 620 | } else { |
| 621 | *target++ = UNI_REPLACEMENT_CHAR; |
| 622 | } |
| 623 | } else { |
| 624 | /* target is a character in range 0xFFFF - 0x10FFFF. */ |
| 625 | if (target + 1 >= targetEnd) { |
nothing calls this directly
no test coverage detected