Merge: lib/core/bytes: Add a redef of has method
authorJean Privat <jean@pryen.org>
Fri, 7 Jun 2019 17:16:29 +0000 (13:16 -0400)
committerJean Privat <jean@pryen.org>
Fri, 7 Jun 2019 17:16:29 +0000 (13:16 -0400)
Adding the redef of the `has` method  to take care of the negative numbers

Signed-off-by: Florian Deljarry <deljarry.florian@gmail.com>

Pull-Request: #2749
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Jean Privat <jean@pryen.org>

lib/core/collection/abstract_collection.nit
lib/core/stream.nit
tests/sav/test_file_read3.res [new file with mode: 0644]
tests/test_file_read3.nit [new file with mode: 0644]

index b51cd22..9e2179b 100644 (file)
@@ -307,6 +307,45 @@ private class StepIterator[E]
        redef fun next_by(step) do real.next_by(step * self.step)
 end
 
+# An iterator that lazyly cache the current item.
+#
+# This class can be used as an helper to build simple iterator with a single and simplier `next_item` method.
+# The only constraint is that `next_item` returns null on the last item, so `null` cannot be a valid element.
+abstract class CachedIterator[E: Object]
+       super Iterator[E]
+
+       # Get the next item if any.
+       # Returns null if there is no next item.
+       fun next_item: nullable E is abstract
+
+       # The last item effectively read.
+       # `null` if on start, after a next of if no more items are available.
+       protected var cache: nullable E = null
+
+       # The current item, if any.
+       # If not, the cache is effectively filled (with `next_item`).
+       # Return `null` iff there is no more elements.
+       protected fun current_item: nullable E
+       do
+               var cache = self.cache
+               if cache != null then return cache
+               cache = next_item
+               self.cache = cache
+               return cache
+       end
+
+       redef fun item do return current_item.as(not null)
+
+       redef fun is_ok do return current_item != null
+
+       redef fun next do
+               # If needed, fill the cache (an consume the current element)
+               current_item
+               # Empty the cache (so the next element will be read)
+               cache = null
+       end
+end
+
 # A collection that contains only one item.
 #
 # Used to pass arguments by reference.
index 152c294..b0486ef 100644 (file)
@@ -484,37 +484,18 @@ end
 # Iterator returned by `Reader::each_line`.
 # See the aforementioned method for details.
 class LineIterator
-       super Iterator[String]
+       super CachedIterator[String]
 
        # The original stream
        var stream: Reader
 
-       redef fun is_ok
+       redef fun next_item
        do
-               var res = not stream.eof
-               if not res and close_on_finish then stream.close
-               return res
-       end
-
-       redef fun item
-       do
-               var line = self.line
-               if line == null then
-                       line = stream.read_line
+               if stream.eof then
+                       if close_on_finish then stream.close
+                       return null
                end
-               self.line = line
-               return line
-       end
-
-       # The last line read (cache)
-       private var line: nullable String = null
-
-       redef fun next
-       do
-               # force the read
-               if line == null then item
-               # drop the line
-               line = null
+               return stream.read_line
        end
 
        # Close the stream when the stream is at the EOF.
diff --git a/tests/sav/test_file_read3.res b/tests/sav/test_file_read3.res
new file mode 100644 (file)
index 0000000..461ab2d
--- /dev/null
@@ -0,0 +1,263 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+true
+#
+true
+# Copyright 2004-2008 Jean Privat <jean@pryen.org>
+true
+#
+true
+# Licensed under the Apache License, Version 2.0 (the "License");
+true
+# you may not use this file except in compliance with the License.
+true
+# You may obtain a copy of the License at
+true
+#
+true
+#     http://www.apache.org/licenses/LICENSE-2.0
+true
+#
+true
+# Unless required by applicable law or agreed to in writing, software
+true
+# distributed under the License is distributed on an "AS IS" BASIS,
+true
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+true
+# See the License for the specific language governing permissions and
+true
+# limitations under the License.
+true
+
+true
+var f = new FileReader.open("test_file_read.nit")
+true
+var s: String
+true
+while not f.eof do
+true
+    s = f.read_line
+true
+    printn(s)
+true
+    printn("\n")
+true
+end
+true
+f.close
+true
+
+true
+f.reopen
+true
+printn(f.read(10))
+true
+printn("|")
+true
+printn(f.read_all)
+true
+---
+true
+# This file is part of NIT ( http://www.nitlanguage.org ).
+true
+# This file is part of NIT ( http://www.nitlanguage.org ).
+true
+true
+#
+true
+#
+true
+true
+# Copyright 2004-2008 Jean Privat <jean@pryen.org>
+true
+# Copyright 2004-2008 Jean Privat <jean@pryen.org>
+true
+true
+#
+true
+#
+true
+true
+# Licensed under the Apache License, Version 2.0 (the "License");
+true
+# Licensed under the Apache License, Version 2.0 (the "License");
+true
+true
+# you may not use this file except in compliance with the License.
+true
+# you may not use this file except in compliance with the License.
+true
+true
+# You may obtain a copy of the License at
+true
+# You may obtain a copy of the License at
+true
+true
+#
+true
+#
+true
+true
+#     http://www.apache.org/licenses/LICENSE-2.0
+true
+#     http://www.apache.org/licenses/LICENSE-2.0
+true
+true
+#
+true
+#
+true
+true
+# Unless required by applicable law or agreed to in writing, software
+true
+# Unless required by applicable law or agreed to in writing, software
+true
+true
+# distributed under the License is distributed on an "AS IS" BASIS,
+true
+# distributed under the License is distributed on an "AS IS" BASIS,
+true
+true
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+true
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+true
+true
+# See the License for the specific language governing permissions and
+true
+# See the License for the specific language governing permissions and
+true
+true
+# limitations under the License.
+true
+# limitations under the License.
+true
+true
+
+true
+
+true
+true
+var f = new FileReader.open("test_file_read.nit")
+true
+var f = new FileReader.open("test_file_read.nit")
+true
+true
+var s: String
+true
+var s: String
+true
+true
+while not f.eof do
+true
+while not f.eof do
+true
+true
+    s = f.read_line
+true
+    s = f.read_line
+true
+true
+    printn(s)
+true
+    printn(s)
+true
+true
+    printn("\n")
+true
+    printn("\n")
+true
+true
+end
+true
+end
+true
+true
+f.close
+true
+f.close
+true
+true
+
+true
+
+true
+true
+f.reopen
+true
+f.reopen
+true
+true
+printn(f.read(10))
+true
+printn(f.read(10))
+true
+true
+printn("|")
+true
+printn("|")
+true
+true
+printn(f.read_all)
+true
+printn(f.read_all)
+true
+---
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+#
+# Copyright 2004-2008 Jean Privat <jean@pryen.org>
+# Copyright 2004-2008 Jean Privat <jean@pryen.org>
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# You may obtain a copy of the License at
+#
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#
+# Unless required by applicable law or agreed to in writing, software
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# limitations under the License.
+
+
+var f = new FileReader.open("test_file_read.nit")
+var f = new FileReader.open("test_file_read.nit")
+var s: String
+var s: String
+while not f.eof do
+while not f.eof do
+    s = f.read_line
+    s = f.read_line
+    printn(s)
+    printn(s)
+    printn("\n")
+    printn("\n")
+end
+end
+f.close
+f.close
+
+
+f.reopen
+f.reopen
+printn(f.read(10))
+printn(f.read(10))
+printn("|")
+printn("|")
+printn(f.read_all)
+printn(f.read_all)
diff --git a/tests/test_file_read3.nit b/tests/test_file_read3.nit
new file mode 100644 (file)
index 0000000..f81a854
--- /dev/null
@@ -0,0 +1,52 @@
+# 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
+var i
+var l = 0
+
+f = new FileReader.open("test_file_read.nit")
+i = f.each_line
+while i.is_ok do
+       l += 1
+       print i.item
+       print i.is_ok
+       i.next
+end
+f.close
+
+print "---"
+
+f = new FileReader.open("test_file_read.nit")
+i = f.each_line
+while i.is_ok do
+       print i.is_ok
+       print i.item
+       print i.is_ok
+       print i.item
+       print i.is_ok
+       i.next
+end
+f.close
+
+print "---"
+
+f = new FileReader.open("test_file_read.nit")
+i = f.each_line
+for x in [0..l[ do
+       print i.item
+       print i.item
+       i.next
+end
+f.close