Skip to content

Commit

Permalink
Optimize String#to_json
Browse files Browse the repository at this point in the history
  • Loading branch information
larubujo committed Dec 26, 2017
1 parent e04565f commit c60de57
Showing 1 changed file with 30 additions and 10 deletions.
40 changes: 30 additions & 10 deletions src/json/builder.cr
Expand Up @@ -94,35 +94,55 @@ class JSON::Builder
# This method can also be used to write the name of an object field.
def string(value)
string = value.to_s

scalar(string: true) do
io << '"'
string.each_char do |char|
case char

pos = 0
reader = Char::Reader.new(string)

while reader.has_next?
set_pos = true
escape = nil

case char = reader.current_char
when '\\'
io << "\\\\"
escape = "\\\\"
when '"'
io << "\\\""
escape = "\\\""
when '\b'
io << "\\b"
escape = "\\b"
when '\f'
io << "\\f"
escape = "\\f"
when '\n'
io << "\\n"
escape = "\\n"
when '\r'
io << "\\r"
escape = "\\r"
when '\t'
io << "\\t"
escape = "\\t"
when .ascii_control?
io.write string.to_slice[pos, reader.pos - pos]
io << "\\u"
ord = char.ord
io << '0' if ord < 0x1000
io << '0' if ord < 0x100
io << '0' if ord < 0x10
ord.to_s(16, io)
else
io << char
set_pos = false
end

if escape
io.write string.to_slice[pos, reader.pos - pos]
io << escape
end

reader.next_char
pos = reader.pos if set_pos
end

io.write string.to_slice[pos, reader.pos - pos]

io << '"'
end
end
Expand Down

0 comments on commit c60de57

Please sign in to comment.