Chromium Code Reviews| Index: runtime/platform/json.cc |
| =================================================================== |
| --- runtime/platform/json.cc (revision 9748) |
| +++ runtime/platform/json.cc (working copy) |
| @@ -97,11 +97,6 @@ |
| // Consume escaped double quote. |
| ++current_pos_; |
| } |
| - } else if (*current_pos_ < 0) { |
| - // UTF-8 not supported. |
| - token_length_ = 0; |
| - token_ = TokenIllegal; |
| - return; |
| } else { |
| ++current_pos_; |
| } |
| @@ -352,6 +347,53 @@ |
| } |
| +void TextBuffer::AddChar(char ch) { |
| + EnsureCapacity(sizeof(ch)); |
| + buf_[msg_len_] = ch; |
| + msg_len_++; |
| + buf_[msg_len_] = '\0'; |
| +} |
| + |
| + |
| +void TextBuffer::AddUTF8(uint32_t ch) { |
| + static const uint32_t kMaxOneByteChar = 0x7F; |
| + static const uint32_t kMaxTwoByteChar = 0x7FF; |
| + static const uint32_t kMaxThreeByteChar = 0xFFFF; |
| + static const uint32_t kMaxFourByteChar = 0x10FFFF; |
| + static const uint32_t kMask = ~(1 << 6); |
| + |
| + EnsureCapacity(sizeof(ch)); |
|
siva
2012/07/18 23:52:24
why do you have two calls to EnsureCapacity, one h
hausner
2012/07/19 00:11:03
Oops, good catch. This is a left-over from a previ
|
| + if (ch <= kMaxOneByteChar) { |
| + EnsureCapacity(1); |
| + buf_[msg_len_++] = ch; |
| + buf_[msg_len_] = '\0'; |
| + return; |
| + } |
| + if (ch <= kMaxTwoByteChar) { |
| + EnsureCapacity(2); |
| + buf_[msg_len_++] = 0xC0 | (ch >> 6); |
| + buf_[msg_len_++] = 0x80 | (ch & kMask); |
| + buf_[msg_len_] = '\0'; |
| + return; |
| + } |
| + if (ch <= kMaxThreeByteChar) { |
| + EnsureCapacity(3); |
| + buf_[msg_len_++] = 0xE0 | (ch >> 12); |
| + buf_[msg_len_++] = 0x80 | ((ch >> 6) & kMask); |
| + buf_[msg_len_++] = 0x80 | (ch & kMask); |
| + buf_[msg_len_] = '\0'; |
| + return; |
| + } |
| + ASSERT(ch <= kMaxFourByteChar); |
| + EnsureCapacity(4); |
| + buf_[msg_len_++] = 0xF0 | (ch >> 18); |
| + buf_[msg_len_++] = 0x80 | ((ch >> 12) & kMask); |
| + buf_[msg_len_++] = 0x80 | ((ch >> 6) & kMask); |
| + buf_[msg_len_++] = 0x80 | (ch & kMask); |
| + buf_[msg_len_] = '\0'; |
| +} |
| + |
| + |
| intptr_t TextBuffer::Printf(const char* format, ...) { |
| va_list args; |
| va_start(args, format); |
| @@ -360,8 +402,7 @@ |
| intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args); |
| va_end(args); |
| if (len >= remaining) { |
| - const int kBufferSpareCapacity = 64; // Somewhat arbitrary. |
| - GrowBuffer(len + kBufferSpareCapacity); |
| + EnsureCapacity(len); |
| remaining = buf_size_ - msg_len_; |
| ASSERT(remaining > len); |
| va_list args2; |
| @@ -376,56 +417,57 @@ |
| } |
| -void TextBuffer::PrintJsonString8(const uint8_t* codepoints, intptr_t length) { |
| - for (intptr_t i = 0; i < length; i++) { |
| - uint8_t cp = codepoints[i]; |
| - switch (cp) { |
| - case '"': |
| - Printf("%s", "\\\""); |
| - break; |
| - case '\\': |
| - Printf("%s", "\\\\"); |
| - break; |
| - case '/': |
| - Printf("%s", "\\/"); |
| - break; |
| - case '\b': |
| - Printf("%s", "\\b"); |
| - break; |
| - case '\f': |
| - Printf("%s", "\\f"); |
| - break; |
| - case '\n': |
| - Printf("%s", "\\n"); |
| - break; |
| - case '\r': |
| - Printf("%s", "\\r"); |
| - break; |
| - case '\t': |
| - Printf("%s", "\\t"); |
| - break; |
| - default: |
| - if ((0x20 <= cp) && (cp <= 0x7e)) { |
| - Printf("%c", cp); |
| - } else { |
| - // Encode character as \u00HH. |
| - uint8_t digit2 = (cp & 0xf0) >> 4; |
| - uint8_t digit3 = cp & 0xf; |
| - Printf("\\u00%c%c", |
| - digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, |
| - digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); |
| - } |
| - } |
| +void TextBuffer::AddEscapedChar(uint32_t cp) { |
| + switch (cp) { |
| + case '"': |
| + Printf("%s", "\\\""); |
| + break; |
| + case '\\': |
| + Printf("%s", "\\\\"); |
| + break; |
| + case '/': |
| + Printf("%s", "\\/"); |
| + break; |
| + case '\b': |
| + Printf("%s", "\\b"); |
| + break; |
| + case '\f': |
| + Printf("%s", "\\f"); |
| + break; |
| + case '\n': |
| + Printf("%s", "\\n"); |
| + break; |
| + case '\r': |
| + Printf("%s", "\\r"); |
| + break; |
| + case '\t': |
| + Printf("%s", "\\t"); |
| + break; |
| + default: |
| + if (cp < 0x20) { |
| + // Encode character as \u00HH. |
| + uint32_t digit2 = (cp >> 4) & 0xf; |
| + uint32_t digit3 = (cp & 0xf); |
| + Printf("\\u00%c%c", |
| + digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, |
| + digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); |
| + } else { |
| + AddUTF8(cp); |
| + } |
| } |
| } |
| -void TextBuffer::GrowBuffer(intptr_t len) { |
| - intptr_t new_size = buf_size_ + len; |
| - char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); |
| - ASSERT(new_buf != NULL); |
| - buf_ = new_buf; |
| - buf_size_ = new_size; |
| +void TextBuffer::EnsureCapacity(intptr_t len) { |
| + intptr_t remaining = buf_size_ - msg_len_; |
| + if (remaining <= len) { |
| + const int kBufferSpareCapacity = 64; // Somewhat arbitrary. |
| + intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; |
|
siva
2012/07/18 23:52:24
you may want to check with Todd on this, he has be
hausner
2012/07/19 00:11:03
Filing a bug and adding a todo.
|
| + char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); |
| + ASSERT(new_buf != NULL); |
| + buf_ = new_buf; |
| + buf_size_ = new_size; |
| + } |
| } |
| } // namespace dart |