lib/standard: Changed semantics of read_char and added read_byte for future uses
authorLucas Bajolet <r4pass@hotmail.com>
Tue, 12 May 2015 15:34:45 +0000 (11:34 -0400)
committerLucas Bajolet <r4pass@hotmail.com>
Tue, 12 May 2015 15:34:45 +0000 (11:34 -0400)
Signed-off-by: Lucas Bajolet <r4pass@hotmail.com>

lib/standard/exec.nit
lib/standard/file.nit
lib/standard/stream.nit
tests/example_wc.nit

index 8cd2f70..cb29312 100644 (file)
@@ -99,6 +99,8 @@ class ProcessReader
 
        redef fun read_char do return stream_in.read_char
 
+       redef fun read_byte do return stream_in.read_byte
+
        redef fun eof do return stream_in.eof
 
        redef fun pipeflags do return 2
index bb87a6f..c0a65f7 100644 (file)
@@ -1217,7 +1217,9 @@ end
 # Read a character from the standard input (`stdin`).
 fun getc: Char
 do
-       return sys.stdin.read_char.ascii
+       var c = sys.stdin.read_char
+       if c == null then return '\1'
+       return c
 end
 
 # Read a line from the standard input (`stdin`).
index e0d3a67..33b9fc2 100644 (file)
@@ -42,8 +42,11 @@ end
 # 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
+       # Read a character. Returns `null` on EOF or timeout
+       fun read_char: nullable Char is abstract
+
+       # Reads a byte, returns `null` if EOF or timeout
+       fun read_byte: nullable Int is abstract
 
        # Read at most i bytes
        fun read(i: Int): String
@@ -52,8 +55,8 @@ abstract class Reader
                var s = new FlatBuffer.with_capacity(i)
                while i > 0 and not eof do
                        var c = read_char
-                       if c >= 0 then
-                               s.add(c.ascii)
+                       if c != null then
+                               s.add(c)
                                i -= 1
                        end
                end
@@ -164,7 +167,7 @@ abstract class Reader
                var s = new FlatBuffer
                while not eof do
                        var c = read_char
-                       if c >= 0 then s.add(c.ascii)
+                       if c != null then s.add(c)
                end
                return s.to_s
        end
@@ -207,12 +210,11 @@ abstract class Reader
                if last_error != null then return
                loop
                        var x = read_char
-                       if x == -1 then
+                       if x == null then
                                if eof then return
                        else
-                               var c = x.ascii
-                               s.chars.push(c)
-                               if c == '\n' then return
+                               s.chars.push(x)
+                               if x == '\n' then return
                        end
                end
        end
@@ -241,14 +243,13 @@ abstract class Reader
        do
                var buf = new FlatBuffer
                var c = read_nonwhitespace
-               if c > 0 then
-                       buf.add(c.ascii)
+               if c != null then
+                       buf.add(c)
                        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)
+                               if c == null then break
+                               if c.is_whitespace then break
+                               buf.add(c)
                        end
                end
                var res = buf.to_s
@@ -258,25 +259,25 @@ abstract class Reader
        # 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.
+       # Returns `null` 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
+       # assert w.read_nonwhitespace == 'a'
+       # assert w.read_nonwhitespace == 'b'
+       # assert w.read_nonwhitespace == 'c'
+       # assert w.read_nonwhitespace == null
        # ~~~
        #
        # `Char::is_whitespace` determines what is a whitespace.
-       fun read_nonwhitespace: Int
+       fun read_nonwhitespace: nullable Char
        do
-               var c = -1
+               var c: nullable Char = null
                while not eof do
                        c = read_char
-                       if c < 0 or not c.ascii.is_whitespace then break
+                       if c == null or not c.is_whitespace then break
                end
                return c
        end
@@ -382,14 +383,26 @@ abstract class BufferedReader
        super Reader
        redef fun read_char
        do
-               if last_error != null then return -1
+               if last_error != null then return null
                if eof then
                        last_error = new IOError("Stream has reached eof")
-                       return -1
+                       return null
                end
-               var c = _buffer.chars[_buffer_pos]
+               var c = _buffer[_buffer_pos]
                _buffer_pos += 1
-               return c.ascii
+               return c
+       end
+
+       redef fun read_byte
+       do
+               if last_error != null then return null
+               if eof then
+                       last_error = new IOError("Stream has reached eof")
+                       return null
+               end
+               var c = _buffer[_buffer_pos].ascii
+               _buffer_pos += 1
+               return c
        end
 
        redef fun read(i)
@@ -431,11 +444,11 @@ abstract class BufferedReader
                loop
                        # First phase: look for a '\n'
                        var i = _buffer_pos
-                       while i < _buffer.length and _buffer.chars[i] != '\n' do i += 1
+                       while i < _buffer.length and _buffer[i] != '\n' do i += 1
 
                        var eol
                        if i < _buffer.length then
-                               assert _buffer.chars[i] == '\n'
+                               assert _buffer[i] == '\n'
                                i += 1
                                eol = true
                        else
@@ -450,7 +463,7 @@ abstract class BufferedReader
                                # Copy from the buffer to the string
                                var j = _buffer_pos
                                while j < i do
-                                       s.add(_buffer.chars[j])
+                                       s.add(_buffer[j])
                                        j += 1
                                end
                                _buffer_pos = i
@@ -539,12 +552,23 @@ class StringReader
 
        redef fun read_char do
                if cursor < source.length then
-                       var c = source[cursor].ascii
+                       var c = source[cursor]
 
                        cursor += 1
                        return c
                else
-                       return -1
+                       return null
+               end
+       end
+
+       redef fun read_byte do
+               if cursor < source.length then
+                       var c = source[cursor]
+
+                       cursor += 1
+                       return c.ascii
+               else
+                       return null
                end
        end
 
index 0bd73fd..7a9e9bd 100644 (file)
@@ -23,17 +23,16 @@ var l = 0
 var inw = false
 while not stdin.eof do
        var i = stdin.read_char
-       if i >= 0 then
-               var x = i.ascii
+       if i != null then
                c = c + 1
-               if x > ' ' then
+               if i > ' ' then
                        if not inw then
                                inw = true
                                w = w + 1
                        end
                else
                        inw = false
-                       if x == '\n' then
+                       if i == '\n' then
                                l = l + 1
                        end
                end