# encoding: utf-8 module HTTPkit class Body def self.build(arg) if arg.is_a?(Body) arg else body = new(arg.to_s) body.closed.fulfill body end end attr_reader :closed # TODO: eliminate string param def initialize(string = '') @io = StringIO.new(string) @closed = Promise.new closed.on_progress { |str| @io.write(str) } end # don't optimize the sync call, we don't wanna search in @io.string # because search time increases with its size. def gets(*args) closed.sync @io.gets(*args) end def read(length = nil, buffer = nil) closed.sync unless optimized_read?(length) @io.read(length, buffer) end def rewind closed.sync @io.rewind end def each(&block) yield_string(&block) closed.on_progress(&block) closed.sync end def to_s closed.sync @io.string end def string @io.string end private def optimized_read?(length) length && length < (@io.length - pos) end def yield_string(&block) block.call(@io.string) unless @io.string.empty? end end end