Using Ruby StringIO's gets method -


if run following code:

require 'stringio' chunked_data = stringio.new("7\r\nhello, \r\n6\r\nworld!\r\n0\r\n") data = "" until chunked_data.eof?   if chunk_head = chunked_data.gets("\r\n")     print chunk_head     if chunk = chunked_data.read(chunk_head.to_i)       print chunk       data << chunk     end   end end 

i output:

7 hello,  6 world! 0 

according docs, gets method takes separator , returns next line based on separator. if replace \r\n in string , separator ., separator functionality seems no longer work , this:

7.hello, .6.world!.0. 

what's going on?

to see what's going on, let's replace print more explicit output:

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}" 

output:

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: "" 

now .:

result = parse(stringio.new("7.hello, .6.world!.0."), ".") puts "    result: #{result.inspect}" 

output:

chunk_head: "7."      chunk: "hello, " chunk_head: "."      chunk: "" chunk_head: "6."      chunk: "world!" chunk_head: "."      chunk: "" chunk_head: "0."      chunk: ""     result: "hello, world!" 

as can see, works either way , result identical.

although result correct, there seems bug in code: don't read separator after chunk. can fixed adding chunked_data.gets(separator) or chunked_data.read(separator.bytesize) after if/end block:

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}" 

output:

chunk_head: "7."      chunk: "hello, " chunk_head: "6."      chunk: "world!" chunk_head: "0."      chunk: ""     result: "hello, world!" 

that looks better.


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -