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 so it can be read by a JSON parser in a string |
592 switch (cp) { | 554 // literal. Use escape sequences for characters other than printable ASCII. |
| 555 void TextBuffer::EscapeAndAddCodeUnit(uint32_t codeunit) { |
| 556 switch (codeunit) { |
593 case '"': | 557 case '"': |
594 Printf("%s", "\\\""); | 558 Printf("%s", "\\\""); |
595 break; | 559 break; |
596 case '\\': | 560 case '\\': |
597 Printf("%s", "\\\\"); | 561 Printf("%s", "\\\\"); |
598 break; | 562 break; |
599 case '/': | 563 case '/': |
600 Printf("%s", "\\/"); | 564 Printf("%s", "\\/"); |
601 break; | 565 break; |
602 case '\b': | 566 case '\b': |
603 Printf("%s", "\\b"); | 567 Printf("%s", "\\b"); |
604 break; | 568 break; |
605 case '\f': | 569 case '\f': |
606 Printf("%s", "\\f"); | 570 Printf("%s", "\\f"); |
607 break; | 571 break; |
608 case '\n': | 572 case '\n': |
609 Printf("%s", "\\n"); | 573 Printf("%s", "\\n"); |
610 break; | 574 break; |
611 case '\r': | 575 case '\r': |
612 Printf("%s", "\\r"); | 576 Printf("%s", "\\r"); |
613 break; | 577 break; |
614 case '\t': | 578 case '\t': |
615 Printf("%s", "\\t"); | 579 Printf("%s", "\\t"); |
616 break; | 580 break; |
617 default: | 581 default: |
618 if (cp < 0x20) { | 582 if (codeunit < 0x20) { |
619 // Encode character as \u00HH. | 583 // Encode character as \u00HH. |
620 uint32_t digit2 = (cp >> 4) & 0xf; | 584 uint32_t digit2 = (codeunit >> 4) & 0xf; |
621 uint32_t digit3 = (cp & 0xf); | 585 uint32_t digit3 = (codeunit & 0xf); |
622 Printf("\\u00%c%c", | 586 Printf("\\u00%c%c", |
623 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, | 587 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, |
624 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); | 588 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); |
| 589 } else if (codeunit > 127) { |
| 590 // Encode character as \uHHHH. |
| 591 uint32_t digit0 = (codeunit >> 12) & 0xf; |
| 592 uint32_t digit1 = (codeunit >> 8) & 0xf; |
| 593 uint32_t digit2 = (codeunit >> 4) & 0xf; |
| 594 uint32_t digit3 = (codeunit & 0xf); |
| 595 Printf("\\u%c%c%c%c", |
| 596 digit0 > 9 ? 'A' + (digit0 - 10) : '0' + digit0, |
| 597 digit1 > 9 ? 'A' + (digit1 - 10) : '0' + digit1, |
| 598 digit2 > 9 ? 'A' + (digit2 - 10) : '0' + digit2, |
| 599 digit3 > 9 ? 'A' + (digit3 - 10) : '0' + digit3); |
625 } else { | 600 } else { |
626 AddUTF8(cp); | 601 AddChar(codeunit); |
627 } | 602 } |
628 } | 603 } |
629 } | 604 } |
630 | 605 |
631 | 606 |
632 void TextBuffer::AddString(const char* s) { | 607 void TextBuffer::AddString(const char* s) { |
633 Printf("%s", s); | 608 Printf("%s", s); |
634 } | 609 } |
635 | 610 |
636 | 611 |
637 void TextBuffer::AddEscapedString(const char* s) { | 612 void TextBuffer::AddEscapedString(const char* s) { |
638 intptr_t len = strlen(s); | 613 intptr_t len = strlen(s); |
639 for (int i = 0; i < len; i++) { | 614 for (int i = 0; i < len; i++) { |
640 AddEscapedChar(s[i]); | 615 EscapeAndAddCodeUnit(s[i]); |
641 } | 616 } |
642 } | 617 } |
643 | 618 |
644 | 619 |
645 void TextBuffer::EnsureCapacity(intptr_t len) { | 620 void TextBuffer::EnsureCapacity(intptr_t len) { |
646 intptr_t remaining = buf_size_ - msg_len_; | 621 intptr_t remaining = buf_size_ - msg_len_; |
647 if (remaining <= len) { | 622 if (remaining <= len) { |
648 const int kBufferSpareCapacity = 64; // Somewhat arbitrary. | 623 const int kBufferSpareCapacity = 64; // Somewhat arbitrary. |
649 // TODO(turnidge): do we need to guard against overflow or other | 624 // TODO(turnidge): do we need to guard against overflow or other |
650 // security issues here? Text buffers are used by the debugger | 625 // security issues here? Text buffers are used by the debugger |
651 // to send user-controlled data (e.g. values of string variables) to | 626 // to send user-controlled data (e.g. values of string variables) to |
652 // the debugger front-end. | 627 // the debugger front-end. |
653 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; | 628 intptr_t new_size = buf_size_ + len + kBufferSpareCapacity; |
654 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); | 629 char* new_buf = reinterpret_cast<char*>(realloc(buf_, new_size)); |
655 ASSERT(new_buf != NULL); | 630 ASSERT(new_buf != NULL); |
656 buf_ = new_buf; | 631 buf_ = new_buf; |
657 buf_size_ = new_size; | 632 buf_size_ = new_size; |
658 } | 633 } |
659 } | 634 } |
660 | 635 |
661 } // namespace dart | 636 } // namespace dart |
OLD | NEW |