+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Additional services for streams.
-module io
-
-import push_back_reader
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Input stream that permits to push bytes back to the stream.
-module io::push_back_reader
-
-# Input stream that permits to push bytes back to the stream.
-class PushBackReader
- super Reader
-
- # Push the specified byte back to the stream.
- #
- # The specified byte is usually the last read byte that is not
- # “unread” already.
- fun unread_char(c: Char) is abstract
-
- # Push the specified string back to the stream.
- #
- # The specified string is usually the last read string that is not
- # “unread” already.
- fun unread(s: String) do
- for c in s.chars.reverse_iterator do unread_char(c)
- end
-end
-
-# Decorates an input stream to permit to push bytes back to the input stream.
-class PushBackDecorator
- super PushBackReader
-
- # The parent stream.
- var parent: Reader
-
- # The stack of the pushed-back bytes.
- #
- # Bytes are in the reverse order they will reappear in the stream.
- # `unread` pushes bytes after already pushed-back bytes.
- #
- # TODO: With optimized bulk array copy operations, a reversed stack (like in
- # OpenJDK) would be more efficient.
- private var buf: Sequence[Char] = new Array[Char]
-
- redef fun read_char: Int do
- if buf.length <= 0 then return parent.read_char
- return buf.pop.ascii
- end
-
- redef fun read(i: Int): String do
- if i <= 0 then return ""
- if buf.length <= 0 then return parent.read(i)
- var s = new FlatBuffer.with_capacity(i)
-
- loop
- s.chars.push(buf.pop)
- i -= 1
- if i <= 0 then
- return s.to_s
- else if buf.length <= 0 then
- s.append(parent.read(i))
- return s.to_s
- end
- end
- end
-
- redef fun read_all: String do
- if buf.length <= 0 then return parent.read_all
- var s = new FlatBuffer
-
- loop
- s.chars.push(buf.pop)
- if buf.length <= 0 then
- s.append(parent.read_all)
- return s.to_s
- end
- end
- end
-
- redef fun append_line_to(s: Buffer) do
- if buf.length > 0 then
- var c: Char
-
- loop
- c = buf.pop
- s.chars.push(c)
- if c == '\n' then return
- if buf.length <= 0 then break
- end
- end
- parent.append_line_to(s)
- end
-
- redef fun eof: Bool do return buf.length <= 0 and parent.eof
-
- redef fun close do
- buf.clear
- parent.close
- end
-
- redef fun unread_char(c: Char) do buf.push(c)
-
- redef fun unread(s: String) do
- for c in s.chars.reverse_iterator do buf.push(c)
- end
-end
+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# This file is free software, which comes along with NIT. This software is
-# distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
-# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE. You can modify it is you want, provided this header
-# is kept unaltered, and a notification of the changes is added.
-# You are allowed to redistribute it and sell it, alone or is a part of
-# another product.
-
-# Test suites for module `push_back_reader`
-module test_push_back_reader is test_suite
-
-import test_suite
-import io::push_back_reader
-
-class TestPushBackDecorator
- super TestSuite
-
- private fun sample: PushBackDecorator do
- return new PushBackDecorator(new StringReader("""
-abcd
-
-efg
-"""))
- end
-
- fun test_read_char do
- var subject = sample
-
- assert 'a' == subject.read_char.ascii
- end
-
- fun test_read_char_eof do
- var subject = new PushBackDecorator(new StringReader(""))
-
- assert -1 == subject.read_char
- end
-
- fun test_unread_read_char do
- var subject = sample
-
- subject.unread_char('z')
- assert 'z' == subject.read_char.ascii
- assert 'a' == subject.read_char.ascii
- end
-
- fun test_read_partial do
- var subject = sample
-
- assert "abcd" == subject.read(4)
- end
-
- fun test_read_too_much do
- var subject = sample
- var exp = """
-abcd
-
-efg
-"""
- assert exp == subject.read(100)
- end
-
- fun test_unread_read do
- var subject = sample
-
- subject.unread("a")
- assert "aab" == subject.read(3)
- end
-
- fun test_unread_read_mixed do
- var subject = sample
-
- subject.unread("a")
- assert "aab" == subject.read(3)
- end
-
- fun test_read_all do
- var subject = sample
- var exp = """
-abcd
-
-efg
-"""
- assert exp == subject.read_all
- end
-
- fun test_unread_read_all do
- var subject = sample
- var exp = """
-fooabcd
-
-efg
-"""
- subject.unread("foo")
- assert exp == subject.read_all
- end
-
- fun test_read_line do
- var subject = sample
-
- assert "abcd" == subject.read_line
- assert "" == subject.read_line
- end
-
- fun test_unread_read_line do
- var subject = sample
-
- subject.unread("a\nb")
- assert "a" == subject.read_line
- assert "babcd" == subject.read_line
- end
-
- fun test_eof do
- var subject = sample
-
- assert not subject.eof
- subject.read_all
- assert subject.eof
- end
-
- fun test_eof_empty do
- var subject = new PushBackDecorator(new StringReader(""))
-
- assert subject.eof
- end
-
- fun test_close do
- var subject = sample
-
- subject.close
- assert subject.eof
- end
-
- fun test_unread_close do
- var subject = sample
-
- subject.unread("foo")
- subject.close
- assert subject.eof
- end
-
- fun test_unread_char_order do
- var subject = sample
-
- subject.unread_char('z')
- subject.unread_char('y')
- assert "yzab" == subject.read(4)
- end
-
- fun test_unread_order do
- var subject = sample
-
- subject.unread("bar")
- subject.unread("foo")
- assert "foobarab" == subject.read(8)
- end
-end
return c.ascii
end
+ # Peeks up to `n` bytes in the buffer, returns an empty string on EOF
+ #
+ # The operation does not consume the buffer
+ #
+ # ~~~nitish
+ # var x = new FileReader("File.txt")
+ # assert x.peek(5) == x.read(5)
+ # ~~~
+ fun peek(i: Int): String do
+ if eof then return ""
+ var b = new FlatBuffer.with_capacity(i)
+ while i > 0 and not eof do
+ b.add _buffer[_buffer_pos]
+ _buffer_pos += 1
+ i -= 1
+ end
+ var nbuflen = b.length + (_buffer.length - _buffer_pos)
+ var nbuf = new FlatBuffer.with_capacity(nbuflen)
+ nbuf.append(b)
+ while _buffer_pos < _buffer.length do
+ nbuf.add(_buffer[_buffer_pos])
+ _buffer_pos += 1
+ end
+ _buffer_pos = 0
+ _buffer = nbuf
+ return b.to_s
+ end
+
redef fun read(i)
do
if last_error != null then return ""
--- /dev/null
+# Thi
+# Thi
+s file is pa
+s file is pa
+rt of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+var f = new FileReader.open("test_peek.nit")
+
+print f.peek(5)
+print f.read(5)
+
+print f.peek(12)
+print f.read(12)
+
+print f.read_all
+
+print f.peek(2)
+
+f.close
+
+
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+var f = new FileReader.open("test_peek.nit")
+
+print f.peek(5)
+print f.read(5)
+
+print f.peek(12)
+print f.read(12)
+
+print f.read_all
+
+print f.peek(2)
+
+f.close