| 539 | /* --------------------------------------------------------------------- */ |
| 540 | |
| 541 | ConversionResult ConvertUTF8toUTF16 ( |
| 542 | const UTF8** sourceStart, const UTF8* sourceEnd, |
| 543 | UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { |
| 544 | ConversionResult result = conversionOK; |
| 545 | const UTF8* source = *sourceStart; |
| 546 | UTF16* target = *targetStart; |
| 547 | while (source < sourceEnd) { |
| 548 | UTF32 ch = 0; |
| 549 | unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; |
| 550 | if (extraBytesToRead >= sourceEnd - source) { |
| 551 | result = sourceExhausted; break; |
| 552 | } |
| 553 | /* Do this check whether lenient or strict */ |
| 554 | if (!isLegalUTF8(source, extraBytesToRead+1)) { |
| 555 | result = sourceIllegal; |
| 556 | break; |
| 557 | } |
| 558 | /* |
| 559 | * The cases all fall through. See "Note A" below. |
| 560 | */ |
| 561 | switch (extraBytesToRead) { |
| 562 | case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ |
| 563 | case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ |
| 564 | case 3: ch += *source++; ch <<= 6; |
| 565 | case 2: ch += *source++; ch <<= 6; |
| 566 | case 1: ch += *source++; ch <<= 6; |
| 567 | case 0: ch += *source++; |
| 568 | } |
| 569 | ch -= offsetsFromUTF8[extraBytesToRead]; |
| 570 | |
| 571 | if (target >= targetEnd) { |
| 572 | source -= (extraBytesToRead+1); /* Back up source pointer! */ |
| 573 | result = targetExhausted; break; |
| 574 | } |
| 575 | if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ |
| 576 | /* UTF-16 surrogate values are illegal in UTF-32 */ |
| 577 | if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { |
| 578 | if (flags == strictConversion) { |
| 579 | source -= (extraBytesToRead+1); /* return to the illegal value itself */ |
| 580 | result = sourceIllegal; |
| 581 | break; |
| 582 | } else { |
| 583 | *target++ = UNI_REPLACEMENT_CHAR; |
| 584 | } |
| 585 | } else { |
| 586 | *target++ = (UTF16)ch; /* normal case */ |
| 587 | } |
| 588 | } else if (ch > UNI_MAX_UTF16) { |
| 589 | if (flags == strictConversion) { |
| 590 | result = sourceIllegal; |
| 591 | source -= (extraBytesToRead+1); /* return to the start */ |
| 592 | break; /* Bail out; shouldn't continue */ |
| 593 | } else { |
| 594 | *target++ = UNI_REPLACEMENT_CHAR; |
| 595 | } |
| 596 | } else { |
| 597 | /* target is a character in range 0xFFFF - 0x10FFFF. */ |
| 598 | if (target + 1 >= targetEnd) { |
nothing calls this directly
no test coverage detected