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 |