Chromium Code Reviews| 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; |
| } |
| } |