| 807 | } |
| 808 | |
| 809 | object parseUtf8(Thread* t, AbstractStream& s, unsigned length) |
| 810 | { |
| 811 | GcByteArray* value = makeByteArray(t, length + 1); |
| 812 | unsigned vi = 0; |
| 813 | for (unsigned si = 0; si < length; ++si) { |
| 814 | unsigned a = s.read1(); |
| 815 | if (a & 0x80) { |
| 816 | if (a & 0x20) { |
| 817 | // 3 bytes |
| 818 | return parseUtf8NonAscii(t, s, value, vi, si, a, NoByte); |
| 819 | } else { |
| 820 | // 2 bytes |
| 821 | unsigned b = s.read1(); |
| 822 | |
| 823 | if (a == 0xC0 and b == 0x80) { |
| 824 | ++si; |
| 825 | assertT(t, si < length); |
| 826 | value->body()[vi++] = 0; |
| 827 | } else { |
| 828 | return parseUtf8NonAscii(t, s, value, vi, si, a, b); |
| 829 | } |
| 830 | } |
| 831 | } else { |
| 832 | value->body()[vi++] = a; |
| 833 | } |
| 834 | } |
| 835 | |
| 836 | if (vi < length) { |
| 837 | PROTECT(t, value); |
| 838 | |
| 839 | GcByteArray* v = makeByteArray(t, vi + 1); |
| 840 | memcpy(v->body().begin(), value->body().begin(), vi); |
| 841 | value = v; |
| 842 | } |
| 843 | |
| 844 | return value; |
| 845 | } |
| 846 | |
| 847 | GcByteArray* makeByteArray(Thread* t, Stream& s, unsigned length) |
| 848 | { |
no test coverage detected