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

Side by Side Diff: runtime/vm/object.cc

Issue 254553003: Generate escape sequence for non-printable ascii characters (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 (value == '\f') || 351 (value == '\f') ||
352 (value == '\b') || 352 (value == '\b') ||
353 (value == '\t') || 353 (value == '\t') ||
354 (value == '\v') || 354 (value == '\v') ||
355 (value == '\r') || 355 (value == '\r') ||
356 (value == '\\') || 356 (value == '\\') ||
357 (value == '$')); 357 (value == '$'));
358 } 358 }
359 359
360 360
361 static bool IsAsciiPrintChar(int32_t code_point) {
362 return (code_point >= ' ') && (code_point <= '~');
363 }
364
365
366 static inline bool IsAsciiNonprintable(int32_t c) {
367 return ((0 <= c) && (c < 32)) || (c == 127);
368 }
369
370
371 static inline bool NeedsEscapeSequence(int32_t c) {
372 return (c == '"') ||
373 (c == '\\') ||
374 (c == '$') ||
375 ((0 <= c) && (c < 32)) ||
Ivan Posva 2014/04/24 21:02:14 || IsAsciiNonPrintable(c);
hausner 2014/04/24 21:30:28 Done.
376 (c == 127);
377 }
378
379
380 static int32_t EscapeOverhead(int32_t c) {
381 if (IsSpecialCharacter(c)) {
382 return 1; // 1 additional byte for the backslash.
383 } else if (IsAsciiNonprintable(c)) {
384 return 3; // 3 additional bytes to encode c as \x00.
385 }
386 return 0;
387 }
388
389
361 template<typename type> 390 template<typename type>
362 static type SpecialCharacter(type value) { 391 static type SpecialCharacter(type value) {
363 if (value == '"') { 392 if (value == '"') {
364 return '"'; 393 return '"';
365 } else if (value == '\n') { 394 } else if (value == '\n') {
366 return 'n'; 395 return 'n';
367 } else if (value == '\f') { 396 } else if (value == '\f') {
368 return 'f'; 397 return 'f';
369 } else if (value == '\b') { 398 } else if (value == '\b') {
370 return 'b'; 399 return 'b';
(...skipping 6717 matching lines...) Expand 10 before | Expand all | Expand 10 after
7088 obj = iterator.CurrentToken(); 7117 obj = iterator.CurrentToken();
7089 literal = iterator.MakeLiteralToken(obj); 7118 literal = iterator.MakeLiteralToken(obj);
7090 // Advance to be able to use next token kind. 7119 // Advance to be able to use next token kind.
7091 iterator.Advance(); 7120 iterator.Advance();
7092 Token::Kind next = iterator.CurrentTokenKind(); 7121 Token::Kind next = iterator.CurrentTokenKind();
7093 7122
7094 // Handle the current token. 7123 // Handle the current token.
7095 if (curr == Token::kSTRING) { 7124 if (curr == Token::kSTRING) {
7096 bool escape_characters = false; 7125 bool escape_characters = false;
7097 for (intptr_t i = 0; i < literal.Length(); i++) { 7126 for (intptr_t i = 0; i < literal.Length(); i++) {
7098 if (IsSpecialCharacter(literal.CharAt(i))) { 7127 if (NeedsEscapeSequence(literal.CharAt(i))) {
7099 escape_characters = true; 7128 escape_characters = true;
7100 } 7129 }
7101 } 7130 }
7102 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) { 7131 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) {
7103 literals.Add(Symbols::DoubleQuotes()); 7132 literals.Add(Symbols::DoubleQuotes());
7104 } 7133 }
7105 if (escape_characters) { 7134 if (escape_characters) {
7106 literal = String::EscapeSpecialCharacters(literal); 7135 literal = String::EscapeSpecialCharacters(literal);
7107 literals.Add(literal); 7136 literals.Add(literal);
7108 } else { 7137 } else {
(...skipping 9140 matching lines...) Expand 10 before | Expand all | Expand 10 after
16249 } 16278 }
16250 const intptr_t len = Utf8::Length(*this); 16279 const intptr_t len = Utf8::Length(*this);
16251 Zone* zone = Isolate::Current()->current_zone(); 16280 Zone* zone = Isolate::Current()->current_zone();
16252 uint8_t* result = zone->Alloc<uint8_t>(len + 1); 16281 uint8_t* result = zone->Alloc<uint8_t>(len + 1);
16253 ToUTF8(result, len); 16282 ToUTF8(result, len);
16254 result[len] = 0; 16283 result[len] = 0;
16255 return reinterpret_cast<const char*>(result); 16284 return reinterpret_cast<const char*>(result);
16256 } 16285 }
16257 16286
16258 16287
16259 static bool IsAsciiPrintChar(intptr_t code_point) {
16260 return code_point >= ' ' && code_point <= '~';
16261 }
16262
16263
16264 // Does not null-terminate. 16288 // Does not null-terminate.
16265 intptr_t String::EscapedString(char* buffer, int max_len) const { 16289 intptr_t String::EscapedString(char* buffer, int max_len) const {
16266 int pos = 0; 16290 int pos = 0;
16267 16291
16268 CodePointIterator cpi(*this); 16292 CodePointIterator cpi(*this);
16269 while (cpi.Next()) { 16293 while (cpi.Next()) {
16270 int32_t code_point = cpi.Current(); 16294 int32_t code_point = cpi.Current();
16271 if (IsSpecialCharacter(code_point)) { 16295 if (IsSpecialCharacter(code_point)) {
16272 if (pos + 2 > max_len) { 16296 if (pos + 2 > max_len) {
16273 return pos; 16297 return pos;
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
16616 index_ = end_; 16640 index_ = end_;
16617 return false; 16641 return false;
16618 } 16642 }
16619 16643
16620 16644
16621 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) { 16645 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str) {
16622 intptr_t len = str.Length(); 16646 intptr_t len = str.Length();
16623 if (len > 0) { 16647 if (len > 0) {
16624 intptr_t num_escapes = 0; 16648 intptr_t num_escapes = 0;
16625 for (intptr_t i = 0; i < len; i++) { 16649 for (intptr_t i = 0; i < len; i++) {
16626 if (IsSpecialCharacter(*CharAddr(str, i))) { 16650 num_escapes += EscapeOverhead(*CharAddr(str, i));
16627 num_escapes += 1;
16628 }
16629 } 16651 }
16630 const String& dststr = String::Handle( 16652 const String& dststr = String::Handle(
16631 OneByteString::New(len + num_escapes, Heap::kNew)); 16653 OneByteString::New(len + num_escapes, Heap::kNew));
16632 intptr_t index = 0; 16654 intptr_t index = 0;
16633 for (intptr_t i = 0; i < len; i++) { 16655 for (intptr_t i = 0; i < len; i++) {
16634 if (IsSpecialCharacter(*CharAddr(str, i))) { 16656 uint8_t ch = *CharAddr(str, i);
Ivan Posva 2014/04/24 21:02:14 GetCharAt?
hausner 2014/04/24 21:30:28 CharAt, actually.
16635 *(CharAddr(dststr, index)) = '\\'; 16657 if (IsSpecialCharacter(ch)) {
16636 *(CharAddr(dststr, index + 1)) = SpecialCharacter(*CharAddr(str, i)); 16658 SetCharAt(dststr, index, '\\');
16659 SetCharAt(dststr, index + 1, SpecialCharacter(ch));
16637 index += 2; 16660 index += 2;
16661 } else if (IsAsciiNonprintable(ch)) {
16662 SetCharAt(dststr, index, '\\');
16663 SetCharAt(dststr, index + 1, 'x');
16664 SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4));
16665 SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF));
16666 index += 4;
16638 } else { 16667 } else {
16639 *(CharAddr(dststr, index)) = *CharAddr(str, i); 16668 SetCharAt(dststr, index, ch);
16640 index += 1; 16669 index += 1;
16641 } 16670 }
16642 } 16671 }
16643 return OneByteString::raw(dststr); 16672 return OneByteString::raw(dststr);
16644 } 16673 }
16645 return OneByteString::raw(Symbols::Empty()); 16674 return OneByteString::raw(Symbols::Empty());
16646 } 16675 }
16647 16676
16677
16648 RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters( 16678 RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters(
16649 const String& str) { 16679 const String& str) {
16650 intptr_t len = str.Length(); 16680 intptr_t len = str.Length();
16651 if (len > 0) { 16681 if (len > 0) {
16652 intptr_t num_escapes = 0; 16682 intptr_t num_escapes = 0;
16653 for (intptr_t i = 0; i < len; i++) { 16683 for (intptr_t i = 0; i < len; i++) {
16654 if (IsSpecialCharacter(*CharAddr(str, i))) { 16684 num_escapes += EscapeOverhead(*CharAddr(str, i));
16655 num_escapes += 1;
16656 }
16657 } 16685 }
16658 const String& dststr = String::Handle( 16686 const String& dststr = String::Handle(
16659 OneByteString::New(len + num_escapes, Heap::kNew)); 16687 OneByteString::New(len + num_escapes, Heap::kNew));
16660 intptr_t index = 0; 16688 intptr_t index = 0;
16661 for (intptr_t i = 0; i < len; i++) { 16689 for (intptr_t i = 0; i < len; i++) {
16662 if (IsSpecialCharacter(*CharAddr(str, i))) { 16690 uint8_t ch = *CharAddr(str, i);
16663 *(OneByteString::CharAddr(dststr, index)) = '\\'; 16691 if (IsSpecialCharacter(ch)) {
16664 *(OneByteString::CharAddr(dststr, index + 1)) = 16692 OneByteString::SetCharAt(dststr, index, '\\');
16665 SpecialCharacter(*CharAddr(str, i)); 16693 OneByteString::SetCharAt(dststr, index + 1, SpecialCharacter(ch));
16666 index += 2; 16694 index += 2;
16695 } else if (IsAsciiNonprintable(ch)) {
16696 OneByteString::SetCharAt(dststr, index, '\\');
16697 OneByteString::SetCharAt(dststr, index + 1, 'x');
16698 OneByteString::SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4));
16699 OneByteString::SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF));
16700 index += 4;
16667 } else { 16701 } else {
16668 *(OneByteString::CharAddr(dststr, index)) = *CharAddr(str, i); 16702 *(OneByteString::CharAddr(dststr, index)) = ch;
16669 index += 1; 16703 index += 1;
16670 } 16704 }
16671 } 16705 }
16672 return OneByteString::raw(dststr); 16706 return OneByteString::raw(dststr);
16673 } 16707 }
16674 return OneByteString::raw(Symbols::Empty()); 16708 return OneByteString::raw(Symbols::Empty());
16675 } 16709 }
16676 16710
16677 16711
16678 RawOneByteString* OneByteString::New(intptr_t len, 16712 RawOneByteString* OneByteString::New(intptr_t len,
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
16879 void* peer) { 16913 void* peer) {
16880 delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer); 16914 delete reinterpret_cast<ExternalStringData<uint8_t>*>(peer);
16881 } 16915 }
16882 16916
16883 16917
16884 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) { 16918 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str) {
16885 intptr_t len = str.Length(); 16919 intptr_t len = str.Length();
16886 if (len > 0) { 16920 if (len > 0) {
16887 intptr_t num_escapes = 0; 16921 intptr_t num_escapes = 0;
16888 for (intptr_t i = 0; i < len; i++) { 16922 for (intptr_t i = 0; i < len; i++) {
16889 if (IsSpecialCharacter(*CharAddr(str, i))) { 16923 num_escapes += EscapeOverhead(*CharAddr(str, i));
16890 num_escapes += 1;
16891 }
16892 } 16924 }
16893 const String& dststr = String::Handle( 16925 const String& dststr = String::Handle(
16894 TwoByteString::New(len + num_escapes, Heap::kNew)); 16926 TwoByteString::New(len + num_escapes, Heap::kNew));
16895 intptr_t index = 0; 16927 intptr_t index = 0;
16896 for (intptr_t i = 0; i < len; i++) { 16928 for (intptr_t i = 0; i < len; i++) {
16897 if (IsSpecialCharacter(*CharAddr(str, i))) { 16929 uint16_t ch = *CharAddr(str, i);
16898 *(CharAddr(dststr, index)) = '\\'; 16930 if (IsSpecialCharacter(ch)) {
16899 *(CharAddr(dststr, index + 1)) = SpecialCharacter(*CharAddr(str, i)); 16931 SetCharAt(dststr, index, '\\');
16932 SetCharAt(dststr, index + 1, SpecialCharacter(ch));
16900 index += 2; 16933 index += 2;
16934 } else if (IsAsciiNonprintable(ch)) {
16935 SetCharAt(dststr, index, '\\');
16936 SetCharAt(dststr, index + 1, 'x');
16937 SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4));
16938 SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF));
16939 index += 4;
16901 } else { 16940 } else {
16902 *(CharAddr(dststr, index)) = *CharAddr(str, i); 16941 SetCharAt(dststr, index, ch);
16903 index += 1; 16942 index += 1;
16904 } 16943 }
16905 } 16944 }
16906 return TwoByteString::raw(dststr); 16945 return TwoByteString::raw(dststr);
16907 } 16946 }
16908 return TwoByteString::New(0, Heap::kNew); 16947 return TwoByteString::New(0, Heap::kNew);
16909 } 16948 }
16910 16949
16911 16950
16912 RawTwoByteString* TwoByteString::New(intptr_t len, 16951 RawTwoByteString* TwoByteString::New(intptr_t len,
(...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after
18553 return tag_label.ToCString(); 18592 return tag_label.ToCString();
18554 } 18593 }
18555 18594
18556 18595
18557 void UserTag::PrintToJSONStream(JSONStream* stream, bool ref) const { 18596 void UserTag::PrintToJSONStream(JSONStream* stream, bool ref) const {
18558 Instance::PrintToJSONStream(stream, ref); 18597 Instance::PrintToJSONStream(stream, ref);
18559 } 18598 }
18560 18599
18561 18600
18562 } // namespace dart 18601 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698