lib: implement `close` in StringOStream
[nit.git] / lib / standard / stream.nit
index 29501ee..a94601c 100644 (file)
 # Input and output streams of characters
 module stream
 
-import string
+intrude import ropes
 
 in "C" `{
        #include <unistd.h>
        #include <poll.h>
        #include <errno.h>
        #include <string.h>
+       #include <signal.h>
 `}
 
 # Abstract stream class
@@ -136,6 +137,29 @@ redef class Text
        redef fun write_to(stream) do stream.write(self)
 end
 
+redef class RopeNode
+       super Streamable
+end
+
+redef class Leaf
+
+       redef fun write_to(s) do s.write(str)
+end
+
+redef class Concat
+
+       redef fun write_to(s)
+       do
+               if left != null then left.write_to(s)
+               if right != null then right.write_to(s)
+       end
+end
+
+redef class RopeString
+
+       redef fun write_to(s) do root.write_to(s)
+end
+
 # Input streams with a buffer
 abstract class BufferedIStream
        super IStream
@@ -155,24 +179,20 @@ abstract class BufferedIStream
 
        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
@@ -399,6 +419,13 @@ class StringOStream
 
        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.to_s)
+       redef fun is_writable do return not closed
+       redef fun write(str)
+       do
+               assert not closed
+               content.add(str.to_s)
+       end
+
+       protected var closed = false
+       redef fun close do closed = true
 end