Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: runtime/platform/json.cc

Issue 192443004: Complete the switch to ServiceObject (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/platform/json.cc
diff --git a/runtime/platform/json.cc b/runtime/platform/json.cc
index a406e7a5728bf96303387fbaa070c0e2af6f55a0..cc57a4b5bd72b676c8794c7977021ff86ec094cd 100644
--- a/runtime/platform/json.cc
+++ b/runtime/platform/json.cc
@@ -642,6 +642,23 @@ void TextBuffer::AddEscapedString(const char* s) {
}
+void TextBuffer::AddEscapedUTF8String(const char* s) {
+ intptr_t len = strlen(s);
+ const uint8_t* s8 = reinterpret_cast<const uint8_t*>(s);
+ intptr_t i = 0;
+ for (; i < len; ) {
+ // Extract next UTF8 character.
+ uint32_t ch = 0;
+ uint32_t ch_len = Utf8Decode(&s8[i], len - i, &ch);
+ ASSERT(ch_len != 0);
+ AddEscapedChar(ch);
+ // Move i forward.
+ i += ch_len;
+ }
+ ASSERT(i == len);
+}
+
+
void TextBuffer::EnsureCapacity(intptr_t len) {
intptr_t remaining = buf_size_ - msg_len_;
if (remaining <= len) {
@@ -658,4 +675,100 @@ void TextBuffer::EnsureCapacity(intptr_t len) {
}
}
+
+static const uint32_t kMaxCodePoint = 0x10FFFF;
turnidge 2014/03/10 21:03:28 I don't like duplicating the existing unicode deco
+
+
+static const int8_t kTrailBytes[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0
+};
+
+
+static const uint32_t kMagicBits[7] = {
+ 0, // Padding.
+ 0x00000000,
+ 0x00003080,
+ 0x000E2080,
+ 0x03C82080,
+ 0xFA082080,
+ 0x82082080
+};
+
+
+// Minimum values of code points used to check shortest form.
+static const uint32_t kOverlongMinimum[7] = {
+ 0, // Padding.
+ 0x0,
+ 0x80,
+ 0x800,
+ 0x10000,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF
+};
+
+
+static bool IsTrailByte(uint8_t code_unit) {
+ return (code_unit & 0xC0) == 0x80;
+}
+
+static bool IsOutOfRange(uint32_t code_point) {
+ return code_point > kMaxCodePoint;
+}
+
+
+static bool IsNonShortestForm(uint32_t code_point, size_t num_code_units) {
+ return code_point < kOverlongMinimum[num_code_units];
+}
+
+static bool IsSurrogate(int32_t ch) {
+ return (ch & 0xFFFFF800) == 0xD800;
+}
+
+uint32_t TextBuffer::Utf8Decode(
+ const uint8_t* utf8_array, intptr_t array_len, uint32_t* dst) {
+ uint32_t ch = utf8_array[0] & 0xFF;
+ intptr_t i = 1;
+ if (ch >= 0x80) {
+ intptr_t num_trail_bytes = kTrailBytes[ch];
+ bool is_malformed = false;
+ for (; i < num_trail_bytes; ++i) {
+ if (i < array_len) {
+ uint8_t code_unit = utf8_array[i];
+ is_malformed |= !IsTrailByte(code_unit);
+ ch = (ch << 6) + code_unit;
+ } else {
+ *dst = -1;
+ return 0;
+ }
+ }
+ ch -= kMagicBits[num_trail_bytes];
+ if (!((is_malformed == false) &&
+ (i == num_trail_bytes) &&
+ !IsOutOfRange(ch) &&
+ !IsNonShortestForm(ch, i) &&
+ !IsSurrogate(ch))) {
+ *dst = -1;
+ return 0;
+ }
+ }
+ *dst = ch;
+ return i;
+}
+
+
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698