Чтобы увидеть, что происходит на самом деле, давайте заменим print
с более явным выходом:
require 'stringio'
def parse(chunked_data, separator)
data = ""
until chunked_data.eof?
if chunk_head = chunked_data.gets(separator)
puts "chunk_head: #{chunk_head.inspect}"
if chunk = chunked_data.read(chunk_head.to_i)
puts " chunk: #{chunk.inspect}"
data << chunk
end
end
end
data
end
result = parse(StringIO.new("7\r\nHello, \r\n6\r\nworld!\r\n0\r\n"), "\r\n")
puts " result: #{result.inspect}"
Выход:
chunk_head: "7\r\n"
chunk: "Hello, "
chunk_head: "\r\n"
chunk: ""
chunk_head: "6\r\n"
chunk: "world!"
chunk_head: "\r\n"
chunk: ""
chunk_head: "0\r\n"
chunk: ""
Теперь с .
:
result = parse(StringIO.new("7.Hello, .6.world!.0."), ".")
puts " result: #{result.inspect}"
Выход:
chunk_head: "7."
chunk: "Hello, "
chunk_head: "."
chunk: ""
chunk_head: "6."
chunk: "world!"
chunk_head: "."
chunk: ""
chunk_head: "0."
chunk: ""
result: "Hello, world!"
Как вы можете видеть, он работает в любом случае, и результат идентичен.
Хотя результат верен, в вашем коде есть ошибка: вы не читаете разделитель после chunk
. Это может быть исправлено путем добавления chunked_data.gets(separator)
или chunked_data.read(separator.bytesize)
после if/end
блока:
def parse(chunked_data, separator)
data = ""
until chunked_data.eof?
if chunk_head = chunked_data.gets(separator)
puts "chunk_head: #{chunk_head.inspect}"
if chunk = chunked_data.read(chunk_head.to_i)
puts " chunk: #{chunk.inspect}"
data << chunk
end
chunked_data.read(separator.bytesize)
end
end
data
end
result = parse(StringIO.new("7.Hello, .6.world!.0."), ".")
puts " result: #{result.inspect}"
Выход:
chunk_head: "7."
chunk: "Hello, "
chunk_head: "6."
chunk: "world!"
chunk_head: "0."
chunk: ""
result: "Hello, world!"
Это выглядит лучше.
Протестируйте свой код, и я получаю тот же результат для '\ r \ n' и' .'. Метод не удаляет разделитель из строки, если это вас смущает. – konart