Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/json.h" | 5 #include "platform/json.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "platform/globals.h" | 8 #include "platform/globals.h" |
| 9 #include "platform/utils.h" | 9 #include "platform/utils.h" |
| 10 #include "vm/os.h" | 10 #include "vm/os.h" |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 | 520 |
| 521 | 521 |
| 522 void TextBuffer::AddChar(char ch) { | 522 void TextBuffer::AddChar(char ch) { |
| 523 EnsureCapacity(sizeof(ch)); | 523 EnsureCapacity(sizeof(ch)); |
| 524 buf_[msg_len_] = ch; | 524 buf_[msg_len_] = ch; |
| 525 msg_len_++; | 525 msg_len_++; |
| 526 buf_[msg_len_] = '\0'; | 526 buf_[msg_len_] = '\0'; |
| 527 } | 527 } |
| 528 | 528 |
| 529 | 529 |
| 530 void TextBuffer::AddUTF8(uint32_t ch) { | |
| 531 static const uint32_t kMaxOneByteChar = 0x7F; | |
| 532 static const uint32_t kMaxTwoByteChar = 0x7FF; | |
| 533 static const uint32_t kMaxThreeByteChar = 0xFFFF; | |
| 534 static const uint32_t kMaxFourByteChar = 0x10FFFF; | |
| 535 static const uint32_t kMask = ~(1 << 6); | |
| 536 | |
| 537 if (ch <= kMaxOneByteChar) { | |
| 538 EnsureCapacity(1); | |
| 539 buf_[msg_len_++] = ch; | |
| 540 buf_[msg_len_] = '\0'; | |
| 541 return; | |
| 542 } | |
| 543 if (ch <= kMaxTwoByteChar) { | |
| 544 EnsureCapacity(2); | |
| 545 buf_[msg_len_++] = 0xC0 | (ch >> 6); | |
| 546 buf_[msg_len_++] = 0x80 | (ch & kMask); | |
| 547 buf_[msg_len_] = '\0'; | |
| 548 return; | |
| 549 } | |
| 550 if (ch <= kMaxThreeByteChar) { | |
| 551 EnsureCapacity(3); | |
| 552 buf_[msg_len_++] = 0xE0 | (ch >> 12); | |
| 553 buf_[msg_len_++] = 0x80 | ((ch >> 6) & kMask); | |
| 554 buf_[msg_len_++] = 0x80 | (ch & kMask); | |
| 555 buf_[msg_len_] = '\0'; | |
| 556 return; | |
| 557 } | |
| 558 ASSERT(ch <= kMaxFourByteChar); | |
| 559 EnsureCapacity(4); | |
| 560 buf_[msg_len_++] = 0xF0 | (ch >> 18); | |
| 561 buf_[msg_len_++] = 0x80 | ((ch >> 12) & kMask); | |
| 562 buf_[msg_len_++] = 0x80 | ((ch >> 6) & kMask); | |
| 563 buf_[msg_len_++] = 0x80 | (ch & kMask); | |
| 564 buf_[msg_len_] = '\0'; | |
| 565 } | |
| 566 | |
| 567 | |
| 568 intptr_t TextBuffer::Printf(const char* format, ...) { | 530 intptr_t TextBuffer::Printf(const char* format, ...) { |
| 569 va_list args; | 531 va_list args; |
| 570 va_start(args, format); | 532 va_start(args, format); |
| 571 intptr_t remaining = buf_size_ - msg_len_; | 533 intptr_t remaining = buf_size_ - msg_len_; |
| 572 ASSERT(remaining >= 0); | 534 ASSERT(remaining >= 0); |
| 573 intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args); | 535 intptr_t len = OS::VSNPrint(buf_ + msg_len_, remaining, format, args); |
| 574 va_end(args); | 536 va_end(args); |
| 575 if (len >= remaining) { | 537 if (len >= remaining) { |
| 576 EnsureCapacity(len); | 538 EnsureCapacity(len); |
| 577 remaining = buf_size_ - msg_len_; | 539 remaining = buf_size_ - msg_len_; |
| 578 ASSERT(remaining > len); | 540 ASSERT(remaining > len); |
| 579 va_list args2; | 541 va_list args2; |
| 580 va_start(args2, format); | 542 va_start(args2, format); |
| 581 intptr_t len2 = OS::VSNPrint(buf_ + msg_len_, remaining, format, args2); | 543 intptr_t len2 = OS::VSNPrint(buf_ + msg_len_, remaining, format, args2); |
| 582 va_end(args2); | 544 va_end(args2); |
| 583 ASSERT(len == len2); | 545 ASSERT(len == len2); |
| 584 } | 546 } |
| 585 msg_len_ += len; | 547 msg_len_ += len; |
| 586 buf_[msg_len_] = '\0'; | 548 buf_[msg_len_] = '\0'; |
| 587 return len; | 549 return len; |
| 588 } | 550 } |
| 589 | 551 |
| 590 | 552 |
| 591 void TextBuffer::AddEscapedChar(uint32_t cp) { | 553 // Write a UTF-16 code unit as |
|
koda
2014/09/10 21:42:07
Finish this comment.
rmacnak
2014/09/10 21:49:59
Done.
| |
| 592 switch (cp) { | 554 void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) { |
|
turnidge
2014/09/10 19:55:28
Can you take a look at json_test and see if it nee
rmacnak
2014/09/10 21:38:49
Added.
| |
| 555 switch (codeunit) { | |
| 593 case '"': | 556 case '"': |
| 594 Printf("%s", "\\\""); | 557 Printf("%s", "\\\""); |
| 595 break; | 558 break; |
| 596 case '\\': | 559 case '\\': |
| 597 Printf("%s", "\\\\"); | 560 Printf("%s", "\\\\"); |
| 598 break; | 561 break; |
| 599 case '/': | 562 case '/': |
| 600 Printf("%s", "\\/"); | 563 Printf("%s", "\\/"); |
| 601 break; | 564 break; |
| 602 case '\b': | 565 case '\b': |
| 603 Printf("%s", "\\b"); | 566 Printf("%s", "\\b"); |
| 604 break; | 567 break; |
| 605 case '\f': | 568 case '\f': |
| 606 Printf("%s", "\\f"); | 569 Printf("%s", "\\f"); |
| 607 break; | 570 break; |
| 608 case '\n': | 571 case '\n': |
| 609 Printf("%s", "\\n"); | 572 Printf("%s", "\\n"); |
| 610 break; | 573 break; |
| 611 case '\r': | 574 case '\r': |
| 612 Printf("%s", "\\r"); | 575 Printf("%s", "\\r"); |
| 613 break; | 576 break; |
| 614 case '\t': | 577 case '\t': |
| 615 Printf("%s", "\\t"); | 578 Printf("%s", "\\t"); |
| 616 break; | 579 break; |
| 617 default: | 580 default: |
| 618 if (cp < 0x20) { | 581 if (codeunit < 0x20) { |
| 619 // Encode character as \u00HH. | 582 // Encode character as \u00HH. |
| 620 uint32_t digit2 = (cp >> 4) & 0xf; | 583 uint32_t digit2 = (codeunit >> 4) & 0xf; |
| 621 uint32_t digit3 = (cp & 0xf); | 584 uint32_t digit3 = (codeunit & 0xf); |
| 622 Printf("\\u00%c%c", | 585 Printf("\\u00%c%c", |
| 623 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, | 586 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, |
| 624 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); | 587 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); |
| 625 } else { | 588 } else if (codeunit > 127) { |
| 626 AddUTF8(cp); | 589 // Encode character as \uHHHH. |
| 590 uint32_t digit1 = (codeunit >> 12) & 0xf; | |
| 591 uint32_t digit2 = (codeunit >> 8) & 0xf; | |
| 592 uint32_t digit3 = (codeunit >> 4) & 0xf; | |
| 593 uint32_t digit4 = (codeunit & 0xf); | |
| 594 Printf("\\u%c%c%c%c", | |
| 595 digit1 > 9 ? 'A' + (digit1 - 10) : '0' + digit1, | |
| 596 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, | |
| 597 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3, | |
| 598 digit4 > 9 ? 'A' + (digit4 - 10) : '0' + digit4); | |
| 599 } else { | |
| 600 AddChar(codeunit); | |
| 627 } | 601 } |
| 628 } | 602 } |
| 629 } | 603 } |
| 630 | 604 |
| 631 | 605 |
| 632 void TextBuffer::AddString(const char* s) { | 606 void TextBuffer::AddString(const char* s) { |
| 633 Printf("%s", s); | 607 Printf("%s", s); |
| 634 } | 608 } |
| 635 | 609 |
| 636 | 610 |
| 637 void TextBuffer::AddEscapedString(const char* s) { | 611 void TextBuffer::AddEscapedString(const char* s) { |
| 638 intptr_t len = strlen(s); | 612 intptr_t len = strlen(s); |
| 639 for (int i = 0; i < len; i++) { | 613 for (int i = 0; i < len; i++) { |
| 640 AddEscapedChar(s[i]); | 614 EscapeAndAddCodeUnit(s[i]); |
| 641 } | 615 } |
| 642 } | 616 } |
| 643 | 617 |
| 644 | 618 |
| 645 void TextBuffer::EnsureCapacity(intptr_t len) { | 619 void TextBuffer::EnsureCapacity(intptr_t len) { |
| 646 intptr_t remaining = buf_size_ - msg_len_; | 620 intptr_t remaining = buf_size_ - msg_len_; |
| 647 if (remaining <= len) { | 621 if (remaining <= len) { |
| 648 const int kBufferSpareCapacity = 64; // Somewhat arbitrary. | 622 const int kBufferSpareCapacity = 64; // Somewhat arbitrary. |
| 649 // TODO(turnidge): do we need to guard against overflow or other | 623 // TODO(turnidge): do we need to guard against overflow or other |
| 650 // security issues here? Text buffers are used by the debugger | 624 // security issues here? Text buffers are used by the debugger |
| 651 // to send user-controlled data (e.g. values of string variables) to | 625 // to send user-controlled data (e.g. values of string variables) to |
| 652 // the debugger front-end. | 626 // the debugger front-end. |
| 653 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; | 627 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; |
| 654 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); | 628 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); |
| 655 ASSERT(new_buf != NULL); | 629 ASSERT(new_buf != NULL); |
| 656 buf_ = new_buf; | 630 buf_ = new_buf; |
| 657 buf_size_ = new_size; | 631 buf_size_ = new_size; |
| 658 } | 632 } |
| 659 } | 633 } |
| 660 | 634 |
| 661 } // namespace dart | 635 } // namespace dart |
| OLD | NEW |