1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # This file is free software, which comes along with NIT. This software is
4 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
5 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
6 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
7 # is kept unaltered, and a notification of the changes is added.
8 # You are allowed to redistribute it and sell it, alone or is a part of
11 # Input stream that permits to push bytes back to the stream.
12 module io
::push_back_reader
14 # Input stream that permits to push bytes back to the stream.
18 # Push the specified byte back to the stream.
20 # The specified byte is usually the last read byte that is not
22 fun unread_char
(c
: Char) is abstract
24 # Push the specified string back to the stream.
26 # The specified string is usually the last read string that is not
28 fun unread
(s
: String) do
29 for c
in s
.chars
.reverse_iterator
do unread_char
(c
)
33 # Decorates an input stream to permit to push bytes back to the input stream.
34 class PushBackDecorator
40 # The stack of the pushed-back bytes.
42 # Bytes are in the reverse order they will reappear in the stream.
43 # `unread` pushes bytes after already pushed-back bytes.
45 # TODO: With optimized bulk array copy operations, a reversed stack (like in
46 # OpenJDK) would be more efficient.
47 private var buf
: Sequence[Char] = new Array[Char]
49 redef fun read_char
: Int do
50 if buf
.length
<= 0 then return parent
.read_char
54 redef fun read
(i
: Int): String do
55 if i
<= 0 then return ""
56 if buf
.length
<= 0 then return parent
.read
(i
)
57 var s
= new FlatBuffer.with_capacity
(i
)
64 else if buf
.length
<= 0 then
65 s
.append
(parent
.read
(i
))
71 redef fun read_all
: String do
72 if buf
.length
<= 0 then return parent
.read_all
73 var s
= new FlatBuffer
77 if buf
.length
<= 0 then
78 s
.append
(parent
.read_all
)
84 redef fun append_line_to
(s
: Buffer) do
85 if buf
.length
> 0 then
91 if c
== '\n' then return
92 if buf
.length
<= 0 then break
95 parent
.append_line_to
(s
)
98 redef fun eof
: Bool do return buf
.length
<= 0 and parent
.eof
105 redef fun unread_char
(c
: Char) do buf
.push
(c
)
107 redef fun unread
(s
: String) do
108 for c
in s
.chars
.reverse_iterator
do buf
.push
(c
)