fun eof: Bool is abstract
end
+# IStream capable of declaring if readable without blocking
+interface PollableIStream
+ super IStream
+
+ # Is there something to read? (without blocking)
+ fun poll_in: Bool is abstract
+
+end
+
# Abstract output stream
interface OStream
super IOS
# write a string
- fun write(s: String) is abstract
+ fun write(s: Text) is abstract
# Can the stream be used to write
fun is_writable: Bool is abstract
end
+# Things that can be efficienlty writen to a OStream
+#
+# The point of this interface it to allow is instance to be efficenty
+# writen into a OStream without having to allocate a big String object
+#
+# ready-to-save documents usually provide this interface.
+interface Streamable
+ # Write itself to a `stream`
+ # The specific logic it let to the concrete subclasses
+ fun write_to(stream: OStream) is abstract
+
+ # Like `write_to` but return a new String (may be quite large)
+ #
+ # This funtionnality is anectodical, since the point
+ # of streamable object to to be efficienlty written to a
+ # stream without having to allocate and concatenate strings
+ fun write_to_string: String
+ do
+ var stream = new StringOStream
+ write_to(stream)
+ return stream.to_s
+ end
+end
+
+redef class Text
+ super Streamable
+ redef fun write_to(stream) do stream.write(self)
+end
+
# Input streams with a buffer
abstract class BufferedIStream
super IStream
redef fun read(i)
do
- var s = new FlatBuffer.with_capacity(i)
- var j = _buffer_pos
- var k = _buffer.length
- while i > 0 do
- if j >= k then
+ if _buffer.length == _buffer_pos then
+ if not eof then
fill_buffer
- if eof then return s.to_s
- j = _buffer_pos
- k = _buffer.length
- end
- while j < k and i > 0 do
- s.add(_buffer.chars[j])
- j += 1
- i -= 1
+ return read(i)
end
+ return ""
end
- _buffer_pos = j
- return s.to_s
+ if _buffer_pos + i >= _buffer.length then
+ var from = _buffer_pos
+ _buffer_pos = _buffer.length
+ return _buffer.substring_from(from).to_s
+ end
+ _buffer_pos += i
+ return _buffer.substring(_buffer_pos - i, i).to_s
end
redef fun read_all
private var content = new Array[String]
redef fun to_s do return content.to_s
redef fun is_writable do return true
- redef fun write(str) do content.add(str)
+ redef fun write(str) do content.add(str.to_s)
end