summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-02-27 11:27:24 +0100
committerEugen Wissner <belka@caraus.de>2017-02-27 11:27:24 +0100
commit43319e4e3a4a5469d07e3b2291b64aa7555dfa95 (patch)
treeb192115b04a8a22ce9bb520587134f02d6676e33
parent33dbf042c2fcd11a191ce209568d8a836277c6f5 (diff)
downloadtanya-43319e4e3a4a5469d07e3b2291b64aa7555dfa95.tar.gz
Initialization from a UTF-16 string
-rw-r--r--source/tanya/container/string.d52
1 files changed, 50 insertions, 2 deletions
diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d
index 07d0c75..75298eb 100644
--- a/source/tanya/container/string.d
+++ b/source/tanya/container/string.d
@@ -5,7 +5,7 @@
/**
* UTF-8 string.
*
- * Copyright: Eugene Wissner 2016-2017.
+ * Copyright: Eugene Wissner 2017.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
@@ -51,6 +51,54 @@ struct String
nothrow @trusted @nogc
{
this(allocator);
+
+ bool overflow;
+ auto size = mulu(str.length, 4, overflow);
+ assert(!overflow);
+
+ reserve(size);
+
+ auto s = data;
+ auto sourceLength = str.length;
+ for (auto c = str.ptr; sourceLength != 0; ++c, --sourceLength)
+ {
+ if (*c < 0x80)
+ {
+ *s++ = *c & 0x7f;
+ length_ += 1;
+ }
+ else if (*c < 0x800)
+ {
+ *s++ = 0xc0 | (*c >> 6) & 0xff;
+ *s++ = 0x80 | (*c & 0x3f);
+ length_ += 2;
+ }
+ else if (*c < 0xd800 || *c - 0xe000 < 0x2000)
+ {
+ *s++ = 0xe0 | (*c >> 12) & 0xff;
+ *s++ = 0x80 | ((*c >> 6) & 0x3f);
+ *s++ = 0x80 | (*c & 0x3f);
+ length_ += 3;
+ }
+ else if ((*c - 0xd800) < 2048 && sourceLength > 0 && *(c + 1) - 0xdc00 < 0x400)
+ { // Surrogate pair
+ dchar d = (*c - 0xd800) | ((*c++ - 0xdc00) >> 10);
+
+ *s++ = 0xf0 | (d >> 18);
+ *s++ = 0x80 | ((d >> 12) & 0x3f);
+ *s++ = 0x80 | ((d >> 6) & 0x3f);
+ *s++ = 0x80 | (d & 0x3f);
+ --sourceLength;
+ length_ += 4;
+ }
+ }
+ }
+
+ ///
+ @safe @nogc unittest
+ {
+ auto s = String("\u10437"w);
+ assert("\u10437" == s.get());
}
/// Ditto.
@@ -101,7 +149,7 @@ struct String
@nogc @safe unittest
{
auto s = String("Отказаться от вина - в этом страшная вина."d);
- assert("Отказаться от вина - в этом страшная вина." == s.get);
+ assert("Отказаться от вина - в этом страшная вина." == s.get());
}
/// Ditto.