From a501f6c233118ca535809610d0c34b7940018249 Mon Sep 17 00:00:00 2001
From: Murai Takashi <tmurai01@gmail.com>
Date: Sun, 19 Jun 2016 19:53:13 +0900
Subject: [PATCH 10/13] utility.cpp: Add encoding / decoding UTF-16LE.
---
.../kernel/partitioning_systems/gpt/utility.cpp | 45 +++++++++++++++++++---
1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/src/add-ons/kernel/partitioning_systems/gpt/utility.cpp b/src/add-ons/kernel/partitioning_systems/gpt/utility.cpp
index 4564377..8b5bfb2 100644
a
|
b
|
void
|
38 | 38 | to_utf8(const uint16* from, size_t maxFromLength, char* to, size_t toSize) |
39 | 39 | { |
40 | 40 | for (uint32 i = 0; i < maxFromLength; i++) { |
41 | | uint16 c = B_LENDIAN_TO_HOST_INT16(from[i]); |
42 | | if (!c) |
| 41 | // Decoding UTF-16LE |
| 42 | uint32 c = 0; |
| 43 | uint16 w1 = B_LENDIAN_TO_HOST_INT16(from[i]); |
| 44 | if (!w1) |
43 | 45 | break; |
44 | 46 | |
| 47 | bool valid = false; |
| 48 | if (w1 < 0xD800 || w1 > 0xDFFF) { |
| 49 | c = w1; |
| 50 | valid = true; |
| 51 | } |
| 52 | |
| 53 | if (!valid && (w1 >= 0xD800 && w1 <= 0xDBFF)) { |
| 54 | if (i + 1 < maxFromLength) { |
| 55 | uint16 w2 = B_LENDIAN_TO_HOST_INT16(from[i + 1]); |
| 56 | if (w2 >= 0xDC00 && w2 <= 0xDFFF) { |
| 57 | c = ((w1 & 0x3FF) << 10) | (w2 & 0x3FF); |
| 58 | c += 0x10000; |
| 59 | ++i; |
| 60 | valid = true; |
| 61 | } |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | if (!valid) break; |
| 66 | |
45 | 67 | if (c < 0x80) |
46 | 68 | put_utf8_byte(to, toSize, c); |
47 | 69 | else if (c < 0x800) { |
… |
… |
to_ucs2(const char* from, size_t fromLength, uint16* to, size_t maxToLength)
|
70 | 92 | { |
71 | 93 | size_t index = 0; |
72 | 94 | while (from[0] != '\0' && index < maxToLength) { |
73 | | // TODO: handle characters that are not representable in UCS-2 better |
74 | | uint32 code = UTF8ToCharCode(&from); |
75 | | if (code < 0x10000) |
76 | | to[index++] = code; |
| 95 | uint32 c = UTF8ToCharCode(&from); |
| 96 | |
| 97 | // Encoding UTF-16LE |
| 98 | if (c > 0x10FFFF) break; // invalid |
| 99 | if (c < 0x10000) { |
| 100 | to[index++] = B_HOST_TO_LENDIAN_INT16(c); |
| 101 | } else { |
| 102 | if (index + 1 >= maxToLength) break; |
| 103 | uint32 c2 = c - 0x10000; |
| 104 | uint16 w1 = 0xD800, w2 = 0xDC00; |
| 105 | w1 = w1 + ((c2 >> 10) & 0x3FF); |
| 106 | w2 = w2 + (c2 & 0x3FF); |
| 107 | to[index++] = B_HOST_TO_LENDIAN_INT16(w1); |
| 108 | to[index++] = B_HOST_TO_LENDIAN_INT16(w2); |
| 109 | } |
77 | 110 | } |
78 | 111 | |
79 | 112 | if (index < maxToLength) |