super Error
end
-# Abstract stream class
-abstract class IOS
+# Any kind of stream to read/write/both to or from a source
+abstract class Stream
# Error produced by the file stream
#
- # var ifs = new IFStream.open("donotmakethisfile.binx")
+ # var ifs = new FileReader.open("donotmakethisfile.binx")
# ifs.read_all
# ifs.close
# assert ifs.last_error != null
fun close is abstract
end
-# Abstract input streams
-abstract class IStream
- super IOS
+# A `Stream` that can be read from
+abstract class Reader
+ super Stream
# Read a character. Return its ASCII value, -1 on EOF or timeout
fun read_char: Int is abstract
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# assert i.read_line == "Hello"
# assert i.read_line == ""
# assert i.read_line == "World"
#
# ~~~
# var txt2 = "Hello\r\n\n\rWorld"
- # var i2 = new StringIStream(txt2)
+ # var i2 = new StringReader(txt2)
# assert i2.read_line == "Hello"
# assert i2.read_line == ""
# assert i2.read_line == "\rWorld"
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# assert i.read_lines == ["Hello", "", "World"]
# ~~~
#
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# assert i.each_line.to_a == ["Hello", "", "World"]
# ~~~
#
# Therefore, the stream should no be closed until the end of the stream.
#
# ~~~
- # i = new StringIStream(txt)
+ # i = new StringReader(txt)
# var el = i.each_line
#
# assert el.item == "Hello"
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# assert i.read_all == txt
# ~~~
fun read_all: String
#
# ~~~
# var txt = "Hello\n\nWorld\n"
- # var i = new StringIStream(txt)
+ # var i = new StringReader(txt)
# var b = new FlatBuffer
# i.append_line_to(b)
# assert b == "Hello\n"
# a non-eol terminated last line was returned.
#
# ~~~
- # var i2 = new StringIStream("hello")
+ # var i2 = new StringReader("hello")
# assert not i2.eof
# var b2 = new FlatBuffer
# i2.append_line_to(b2)
# Is there something to read.
# This function returns 'false' if there is something to read.
fun eof: Bool is abstract
+
+ # Read the next sequence of non whitespace characters.
+ #
+ # Leading whitespace characters are skipped.
+ # The first whitespace character that follows the result is consumed.
+ #
+ # An empty string is returned if the end of the file or an error is encounter.
+ #
+ # ~~~
+ # var w = new StringReader(" Hello, \n\t World!")
+ # assert w.read_word == "Hello,"
+ # assert w.read_char == '\n'.ascii
+ # assert w.read_word == "World!"
+ # assert w.read_word == ""
+ # ~~~
+ #
+ # `Char::is_whitespace` determines what is a whitespace.
+ fun read_word: String
+ do
+ var buf = new FlatBuffer
+ var c = read_nonwhitespace
+ if c > 0 then
+ buf.add(c.ascii)
+ while not eof do
+ c = read_char
+ if c < 0 then break
+ var a = c.ascii
+ if a.is_whitespace then break
+ buf.add(a)
+ end
+ end
+ var res = buf.to_s
+ return res
+ end
+
+ # Skip whitespace characters (if any) then return the following non-whitespace character.
+ #
+ # Returns the code point of the character.
+ # Return -1 on end of file or error.
+ #
+ # In fact, this method works like `read_char` except it skips whitespace.
+ #
+ # ~~~
+ # var w = new StringReader(" \nab\tc")
+ # assert w.read_nonwhitespace == 'a'.ascii
+ # assert w.read_nonwhitespace == 'b'.ascii
+ # assert w.read_nonwhitespace == 'c'.ascii
+ # assert w.read_nonwhitespace == -1
+ # ~~~
+ #
+ # `Char::is_whitespace` determines what is a whitespace.
+ fun read_nonwhitespace: Int
+ do
+ var c = -1
+ while not eof do
+ c = read_char
+ if c < 0 or not c.ascii.is_whitespace then break
+ end
+ return c
+ end
end
-# Iterator returned by `IStream::each_line`.
+# Iterator returned by `Reader::each_line`.
# See the aforementioned method for details.
class LineIterator
super Iterator[String]
# The original stream
- var stream: IStream
+ var stream: Reader
redef fun is_ok
do
end
end
-# IStream capable of declaring if readable without blocking
-abstract class PollableIStream
- super IStream
+# `Reader` capable of declaring if readable without blocking
+abstract class PollableReader
+ super Reader
# Is there something to read? (without blocking)
fun poll_in: Bool is abstract
end
-# Abstract output stream
-abstract class OStream
- super IOS
+# A `Stream` that can be written to
+abstract class Writer
+ super Stream
# write a string
fun write(s: Text) is abstract
fun is_writable: Bool is abstract
end
-# Things that can be efficienlty writen to a OStream
+# Things that can be efficienlty written to a `Writer`
#
-# 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
+# The point of this interface is to allow the instance to be efficiently
+# written into a `Writer`.
#
-# ready-to-save documents usually provide this interface.
-interface Streamable
+# Ready-to-save documents usually provide this interface.
+interface Writable
# Write itself to a `stream`
# The specific logic it let to the concrete subclasses
- fun write_to(stream: OStream) is abstract
+ fun write_to(stream: Writer) is abstract
# Like `write_to` but return a new String (may be quite large)
#
# stream without having to allocate and concatenate strings
fun write_to_string: String
do
- var stream = new StringOStream
+ var stream = new StringWriter
write_to(stream)
return stream.to_s
end
end
redef class Text
- super Streamable
+ super Writable
redef fun write_to(stream) do stream.write(self)
end
-# Input streams with a buffer
-abstract class BufferedIStream
- super IStream
+# Input streams with a buffered input for efficiency purposes
+abstract class BufferedReader
+ super Reader
redef fun read_char
do
if last_error != null then return -1
end
end
-# An Input/Output Stream
-abstract class IOStream
- super IStream
- super OStream
+# A `Stream` that can be written to and read from
+abstract class Duplex
+ super Reader
+ super Writer
end
-# Stream to a String.
+# `Stream` that can be used to write to a `String`
#
-# Mainly used for compatibility with OStream type and tests.
-class StringOStream
- super OStream
+# Mainly used for compatibility with Writer type and tests.
+class StringWriter
+ super Writer
private var content = new Array[String]
redef fun to_s do return content.to_s
redef fun close do closed = true
end
-# Stream from a String.
+# `Stream` used to read from a `String`
#
-# Mainly used for compatibility with IStream type and tests.
-class StringIStream
- super IStream
+# Mainly used for compatibility with Reader type and tests.
+class StringReader
+ super Reader
# The string to read from.
var source: String