1+ from utils import StringSlice
12from memory import Span
23from pathlib import Path
34from python import Python
45from tensor import Tensor
56from testing import *
67
7- from ExtraMojo.fs.file import (
8- FileReader,
8+ from ExtraMojo.bstr.bstr import SplitIterator
9+ from ExtraMojo.io.delimited import (
10+ DelimReader,
11+ FromDelimited,
12+ ToDelimited,
13+ DelimWriter,
14+ )
15+ from ExtraMojo.io.buffered import (
16+ BufferedReader,
917 read_lines,
1018 for_each_line,
1119 BufferedWriter,
@@ -22,26 +30,71 @@ fn s(bytes: Span[UInt8]) -> String:
2230fn strings_for_writing (size : Int) -> List[String]:
2331 var result = List[String]()
2432 for i in range (size):
25- result.append(" Line: " + str (i) + " X" + (" -" * 64 )) # make lines long
33+ result.append(
34+ " Line: " + String(i) + " X" + (" -" * 64 )
35+ ) # make lines long
2636 return result
2737
2838
2939fn test_read_until (file : Path, expected_lines : List[String]) raises :
40+ var buffer_capacities = List(10 , 100 , 200 , 500 )
41+ for cap in buffer_capacities:
42+ var fh = open (file , " r" )
43+ var reader = BufferedReader(fh^ , buffer_capacity = cap[])
44+ var buffer = List[UInt8]()
45+ var counter = 0
46+ while reader.read_until(buffer) != 0 :
47+ assert_equal(List(expected_lines[counter].as_bytes()), buffer)
48+ counter += 1
49+
50+ assert_equal(counter, len (expected_lines))
51+ print (" Successful read_until with buffer capacity of {} " .format(cap[]))
52+
53+
54+ fn test_read_until_return_trailing (
55+ file : Path, expected_lines : List[String]
56+ ) raises :
3057 var fh = open (file , " r" )
31- var reader = FileReader (fh^ , buffer_size = 200 )
58+ var reader = BufferedReader (fh^ , buffer_capacity = 200 )
3259 var buffer = List[UInt8]()
3360 var counter = 0
3461 while reader.read_until(buffer) != 0 :
3562 assert_equal(List(expected_lines[counter].as_bytes()), buffer)
3663 counter += 1
3764 assert_equal(counter, len (expected_lines))
38- print (" Successful read_until" )
65+ print (" Successful read_until_return_trailing" )
66+
67+
68+ fn test_read_bytes (file : Path) raises :
69+ var fh = open (file , " r" )
70+ var reader = BufferedReader(fh^ , buffer_capacity = 50 )
71+ var buffer = List[UInt8](capacity = 125 )
72+ for _ in range (0 , 125 ):
73+ buffer.append(0 )
74+ var found_file = List[UInt8]()
75+
76+ # Read bytes from the buf reader, copy to found
77+ var bytes_read = 0
78+ while True :
79+ bytes_read = reader.read_bytes(buffer)
80+ if bytes_read == 0 :
81+ break
82+ found_file.extend(buffer[0 :bytes_read])
83+ # Last usage of reader, meaning it should call __del__ here.
84+
85+ var expected = open (file , " r" ).read().as_bytes()
86+ assert_equal(len (expected), len (found_file))
87+ for i in range (0 , len (expected)):
88+ assert_equal(
89+ expected[i], found_file[i], msg = " Unequal at byte: " + String(i)
90+ )
91+ print (" Successful read_bytes" )
3992
4093
4194fn test_context_manager_simple (file : Path, expected_lines : List[String]) raises :
4295 var buffer = List[UInt8]()
4396 var counter = 0
44- with FileReader (open (file , " r" ), buffer_size = 200 ) as reader:
97+ with BufferedReader (open (file , " r" ), buffer_capacity = 200 ) as reader:
4598 while reader.read_until(buffer) != 0 :
4699 assert_equal(List(expected_lines[counter].as_bytes()), buffer)
47100 counter += 1
@@ -50,7 +103,7 @@ fn test_context_manager_simple(file: Path, expected_lines: List[String]) raises:
50103
51104
52105fn test_read_lines (file : Path, expected_lines : List[String]) raises :
53- var lines = read_lines(str (file ))
106+ var lines = read_lines(String (file ))
54107 assert_equal(len (lines), len (expected_lines))
55108 for i in range (0 , len (lines)):
56109 assert_equal(lines[i], List(expected_lines[i].as_bytes()))
@@ -67,55 +120,103 @@ fn test_for_each_line(file: Path, expected_lines: List[String]) raises:
67120 found_bad = True
68121 counter += 1
69122
70- for_each_line[inner](str (file ))
123+ for_each_line[inner](String (file ))
71124 assert_false(found_bad)
72125 print (" Successful for_each_line" )
73126
74127
75- # https://github.com/modularml/mojo/issues/1753
76- # fn test_stringify() raises:
77- # var example = List[Int8]()
78- # example.append(ord("e"))
79- # example.append(ord("x"))
80-
81- # var container = List[Int8]()
82- # for i in range(len(example)):
83- # container.append(example[i])
84- # var stringifed = String(container)
85- # assert_equal("ex", stringifed)
86- # # Unhandled exception caught during execution: AssertionError: ex is not equal to e
128+ @value
129+ struct SerDerStruct (ToDelimited , FromDelimited ):
130+ var index : Int
131+ var name : String
132+
133+ fn write_to_delimited (read self , mut writer : DelimWriter) raises :
134+ writer.write_record(self .index, self .name)
135+
136+ fn write_header (read self , mut writer : DelimWriter) raises :
137+ writer.write_record(" index" , " name" )
138+
139+ @ staticmethod
140+ fn from_delimited (mut data : SplitIterator) raises -> Self:
141+ var index = Int(StringSlice(unsafe_from_utf8 = data.__next__ ()))
142+ var name = String() # String constructor expected nul terminated byte span
143+ name.write_bytes(data.__next__ ())
144+ return Self(index, name)
145+
146+
147+ fn test_delim_reader_writer (file : Path) raises :
148+ var to_write = List[SerDerStruct]()
149+ for i in range (0 , 1000 ):
150+ to_write.append(SerDerStruct(i, String(" MyNameIs" + String(i))))
151+ var writer = DelimWriter(
152+ BufferedWriter(open (String(file ), " w" )), delim = " \t " , write_header = True
153+ )
154+ for item in to_write:
155+ writer.serialize(item[])
156+ writer.flush()
157+ writer.close()
158+
159+ var reader = DelimReader[SerDerStruct](
160+ BufferedReader(open (String(file ), " r" )),
161+ delim = ord (" \t " ),
162+ has_header = True ,
163+ )
164+ var count = 0
165+ for item in reader^ :
166+ assert_equal(to_write[count].index, item.index)
167+ assert_equal(to_write[count].name, item.name)
168+ count += 1
169+ assert_equal(count, len (to_write))
170+ print (" Successful delim_writer" )
87171
88172
89173fn test_buffered_writer (file : Path, expected_lines : List[String]) raises :
90- var fh = BufferedWriter(open (str (file ), " w" ), buffer_capacity = 128 )
174+ var fh = BufferedWriter(open (String (file ), " w" ), buffer_capacity = 128 )
91175 for i in range (len (expected_lines)):
92176 fh.write_bytes(expected_lines[i].as_bytes())
93177 fh.write_bytes(" \n " .as_bytes())
178+ fh.flush()
94179 fh.close()
95180
96- test_read_until(str (file ), expected_lines)
181+ test_read_until(String (file ), expected_lines)
97182
98183
99184fn create_file (path : String, lines : List[String]) raises :
100185 with open (path, " w" ) as fh:
101186 for i in range (len (lines)):
102187 fh.write(lines[i])
103- fh.write(str (" \n " ))
188+ fh.write(String(" \n " ))
189+
190+
191+ fn create_file_no_trailing_newline (path : String, lines : List[String]) raises :
192+ with open (path, " w" ) as fh:
193+ for i in range (len (lines)):
194+ fh.write(lines[i])
195+ if i != len (lines) - 1 :
196+ fh.write(String(" \n " ))
104197
105198
106199fn main () raises :
107- # TODO : use python to create a tempdir
108200 var tempfile = Python.import_module(" tempfile" )
109201 var tempdir = tempfile.TemporaryDirectory()
110- var file = Path(str (tempdir.name)) / " lines.txt"
202+ var file = Path(String(tempdir.name)) / " lines.txt"
203+ var file_no_trailing_newline = Path(
204+ String(tempdir.name)
205+ ) / " lines_no_trailing_newline.txt"
111206 var strings = strings_for_writing(10000 )
112- create_file(str (file ), strings)
207+ create_file(String(file ), strings)
208+ create_file_no_trailing_newline(String(file_no_trailing_newline), strings)
113209
114210 # Tests
115- test_read_until(str (file ), strings)
116- test_read_lines(str (file ), strings)
117- test_for_each_line(str (file ), strings)
118- test_buffered_writer(str (file ), strings)
211+ test_read_until(String(file ), strings)
212+ test_read_until_return_trailing(String(file_no_trailing_newline), strings)
213+ test_read_bytes(String(file ))
214+ test_read_lines(String(file ), strings)
215+ test_for_each_line(String(file ), strings)
216+ var buf_writer_file = Path(String(tempdir.name)) / " buf_writer.txt"
217+ test_buffered_writer(String(buf_writer_file), strings)
218+ var delim_file = Path(String(tempdir.name)) / " delim.txt"
219+ test_delim_reader_writer(String(delim_file))
119220
120221 print (" SUCCESS" )
121222
0 commit comments