 Chromium Code Reviews
 Chromium Code Reviews Issue 254553003:
  Generate escape sequence for non-printable ascii characters  (Closed) 
  Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
    
  
    Issue 254553003:
  Generate escape sequence for non-printable ascii characters  (Closed) 
  Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/| Index: runtime/vm/object.cc | 
| =================================================================== | 
| --- runtime/vm/object.cc (revision 35374) | 
| +++ runtime/vm/object.cc (working copy) | 
| @@ -358,6 +358,35 @@ | 
| } | 
| +static bool IsAsciiPrintChar(int32_t code_point) { | 
| + return (code_point >= ' ') && (code_point <= '~'); | 
| +} | 
| + | 
| + | 
| +static inline bool IsAsciiNonprintable(int32_t c) { | 
| + return ((0 <= c) && (c < 32)) || (c == 127); | 
| +} | 
| + | 
| + | 
| +static inline bool NeedsEscapeSequence(int32_t c) { | 
| + return (c == '"') || | 
| + (c == '\\') || | 
| + (c == '$') || | 
| + ((0 <= c) && (c < 32)) || | 
| 
Ivan Posva
2014/04/24 21:02:14
|| IsAsciiNonPrintable(c);
 
hausner
2014/04/24 21:30:28
Done.
 | 
| + (c == 127); | 
| +} | 
| + | 
| + | 
| +static int32_t EscapeOverhead(int32_t c) { | 
| + if (IsSpecialCharacter(c)) { | 
| + return 1; // 1 additional byte for the backslash. | 
| + } else if (IsAsciiNonprintable(c)) { | 
| + return 3; // 3 additional bytes to encode c as \x00. | 
| + } | 
| + return 0; | 
| +} | 
| + | 
| + | 
| template<typename type> | 
| static type SpecialCharacter(type value) { | 
| if (value == '"') { | 
| @@ -7095,7 +7124,7 @@ | 
| if (curr == Token::kSTRING) { | 
| bool escape_characters = false; | 
| for (intptr_t i = 0; i < literal.Length(); i++) { | 
| - if (IsSpecialCharacter(literal.CharAt(i))) { | 
| + if (NeedsEscapeSequence(literal.CharAt(i))) { | 
| escape_characters = true; | 
| } | 
| } | 
| @@ -16256,11 +16285,6 @@ | 
| } | 
| -static bool IsAsciiPrintChar(intptr_t code_point) { | 
| - return code_point >= ' ' && code_point <= '~'; | 
| -} | 
| - | 
| - | 
| // Does not null-terminate. | 
| intptr_t String::EscapedString(char* buffer, int max_len) const { | 
| int pos = 0; | 
| @@ -16623,20 +16647,25 @@ | 
| if (len > 0) { | 
| intptr_t num_escapes = 0; | 
| for (intptr_t i = 0; i < len; i++) { | 
| - if (IsSpecialCharacter(*CharAddr(str, i))) { | 
| - num_escapes += 1; | 
| - } | 
| + num_escapes += EscapeOverhead(*CharAddr(str, i)); | 
| } | 
| const String& dststr = String::Handle( | 
| OneByteString::New(len + num_escapes, Heap::kNew)); | 
| intptr_t index = 0; | 
| for (intptr_t i = 0; i < len; i++) { | 
| - if (IsSpecialCharacter(*CharAddr(str, i))) { | 
| - *(CharAddr(dststr, index)) = '\\'; | 
| - *(CharAddr(dststr, index + 1)) = SpecialCharacter(*CharAddr(str, i)); | 
| + uint8_t ch = *CharAddr(str, i); | 
| 
Ivan Posva
2014/04/24 21:02:14
GetCharAt?
 
hausner
2014/04/24 21:30:28
CharAt, actually.
 | 
| + if (IsSpecialCharacter(ch)) { | 
| + SetCharAt(dststr, index, '\\'); | 
| + SetCharAt(dststr, index + 1, SpecialCharacter(ch)); | 
| index += 2; | 
| + } else if (IsAsciiNonprintable(ch)) { | 
| + SetCharAt(dststr, index, '\\'); | 
| + SetCharAt(dststr, index + 1, 'x'); | 
| + SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4)); | 
| + SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF)); | 
| + index += 4; | 
| } else { | 
| - *(CharAddr(dststr, index)) = *CharAddr(str, i); | 
| + SetCharAt(dststr, index, ch); | 
| index += 1; | 
| } | 
| } | 
| @@ -16645,27 +16674,32 @@ | 
| return OneByteString::raw(Symbols::Empty()); | 
| } | 
| + | 
| RawOneByteString* ExternalOneByteString::EscapeSpecialCharacters( | 
| const String& str) { | 
| intptr_t len = str.Length(); | 
| if (len > 0) { | 
| intptr_t num_escapes = 0; | 
| for (intptr_t i = 0; i < len; i++) { | 
| - if (IsSpecialCharacter(*CharAddr(str, i))) { | 
| - num_escapes += 1; | 
| - } | 
| + num_escapes += EscapeOverhead(*CharAddr(str, i)); | 
| } | 
| const String& dststr = String::Handle( | 
| OneByteString::New(len + num_escapes, Heap::kNew)); | 
| intptr_t index = 0; | 
| for (intptr_t i = 0; i < len; i++) { | 
| - if (IsSpecialCharacter(*CharAddr(str, i))) { | 
| - *(OneByteString::CharAddr(dststr, index)) = '\\'; | 
| - *(OneByteString::CharAddr(dststr, index + 1)) = | 
| - SpecialCharacter(*CharAddr(str, i)); | 
| + uint8_t ch = *CharAddr(str, i); | 
| + if (IsSpecialCharacter(ch)) { | 
| + OneByteString::SetCharAt(dststr, index, '\\'); | 
| + OneByteString::SetCharAt(dststr, index + 1, SpecialCharacter(ch)); | 
| index += 2; | 
| + } else if (IsAsciiNonprintable(ch)) { | 
| + OneByteString::SetCharAt(dststr, index, '\\'); | 
| + OneByteString::SetCharAt(dststr, index + 1, 'x'); | 
| + OneByteString::SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4)); | 
| + OneByteString::SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF)); | 
| + index += 4; | 
| } else { | 
| - *(OneByteString::CharAddr(dststr, index)) = *CharAddr(str, i); | 
| + *(OneByteString::CharAddr(dststr, index)) = ch; | 
| index += 1; | 
| } | 
| } | 
| @@ -16886,20 +16920,25 @@ | 
| if (len > 0) { | 
| intptr_t num_escapes = 0; | 
| for (intptr_t i = 0; i < len; i++) { | 
| - if (IsSpecialCharacter(*CharAddr(str, i))) { | 
| - num_escapes += 1; | 
| - } | 
| + num_escapes += EscapeOverhead(*CharAddr(str, i)); | 
| } | 
| const String& dststr = String::Handle( | 
| TwoByteString::New(len + num_escapes, Heap::kNew)); | 
| intptr_t index = 0; | 
| for (intptr_t i = 0; i < len; i++) { | 
| - if (IsSpecialCharacter(*CharAddr(str, i))) { | 
| - *(CharAddr(dststr, index)) = '\\'; | 
| - *(CharAddr(dststr, index + 1)) = SpecialCharacter(*CharAddr(str, i)); | 
| + uint16_t ch = *CharAddr(str, i); | 
| + if (IsSpecialCharacter(ch)) { | 
| + SetCharAt(dststr, index, '\\'); | 
| + SetCharAt(dststr, index + 1, SpecialCharacter(ch)); | 
| index += 2; | 
| + } else if (IsAsciiNonprintable(ch)) { | 
| + SetCharAt(dststr, index, '\\'); | 
| + SetCharAt(dststr, index + 1, 'x'); | 
| + SetCharAt(dststr, index + 2, GetHexCharacter(ch >> 4)); | 
| + SetCharAt(dststr, index + 3, GetHexCharacter(ch & 0xF)); | 
| + index += 4; | 
| } else { | 
| - *(CharAddr(dststr, index)) = *CharAddr(str, i); | 
| + SetCharAt(dststr, index, ch); | 
| index += 1; | 
| } | 
| } |