| 1 | module string_reader |
| 2 | |
| 3 | import io |
| 4 | |
| 5 | struct Buf { |
| 6 | pub: |
| 7 | bytes []u8 |
| 8 | mut: |
| 9 | i int |
| 10 | } |
| 11 | |
| 12 | struct TwoByteReader { |
| 13 | mut: |
| 14 | data string |
| 15 | pos int |
| 16 | } |
| 17 | |
| 18 | fn (mut b Buf) read(mut buf []u8) !int { |
| 19 | if !(b.i < b.bytes.len) { |
| 20 | return io.Eof{} |
| 21 | } |
| 22 | n := copy(mut buf, b.bytes[b.i..]) |
| 23 | b.i += n |
| 24 | return n |
| 25 | } |
| 26 | |
| 27 | fn (mut r TwoByteReader) read(mut buf []u8) !int { |
| 28 | if r.pos >= r.data.len { |
| 29 | return io.Eof{} |
| 30 | } |
| 31 | min := int_min(int_min(r.data.len - r.pos, 2), buf.len) |
| 32 | for i in 0 .. min { |
| 33 | buf[i] = r.data[r.pos] |
| 34 | r.pos++ |
| 35 | } |
| 36 | return min |
| 37 | } |
| 38 | |
| 39 | fn read_from_reader_interface(mut r io.Reader, mut buf []u8) !int { |
| 40 | return r.read(mut buf) |
| 41 | } |
| 42 | |
| 43 | fn test_read_all() { |
| 44 | mut reader := StringReader.new() |
| 45 | |
| 46 | if _ := reader.read_all(false) { |
| 47 | assert false, 'should return io.Eof' |
| 48 | } else { |
| 49 | assert err is io.Eof |
| 50 | } |
| 51 | |
| 52 | contents := 'test string' |
| 53 | buf := Buf{ |
| 54 | bytes: contents.bytes() |
| 55 | } |
| 56 | |
| 57 | reader = StringReader.new(reader: buf) |
| 58 | data := reader.read_all(false)! |
| 59 | |
| 60 | assert data == contents |
| 61 | } |
| 62 | |
| 63 | fn test_read_bytes() { |
| 64 | mut reader := StringReader.new() |
| 65 | |
| 66 | if _ := reader.read_bytes(4) { |
| 67 | assert false, 'should return io.Eof' |
| 68 | } else { |
| 69 | assert err.msg() == 'reader is not set' |
| 70 | } |
| 71 | |
| 72 | buf := Buf{ |
| 73 | bytes: '12345678'.bytes() |
| 74 | } |
| 75 | |
| 76 | reader = StringReader.new(reader: buf) |
| 77 | mut data := reader.read_bytes(4)! |
| 78 | assert data == buf.bytes[..4] |
| 79 | |
| 80 | data = reader.read_bytes(4)! |
| 81 | assert data == buf.bytes[4..8] |
| 82 | } |
| 83 | |
| 84 | fn test_read_line() { |
| 85 | mut reader := StringReader.new() |
| 86 | |
| 87 | if _ := reader.read_line() { |
| 88 | assert false, 'should return io.Eof' |
| 89 | } else { |
| 90 | assert err is io.Eof |
| 91 | } |
| 92 | |
| 93 | buf := Buf{ |
| 94 | bytes: 'first line\r\nsecond line\n'.bytes() |
| 95 | } |
| 96 | |
| 97 | reader = StringReader.new(reader: buf) |
| 98 | |
| 99 | assert reader.read_line()! == 'first line' |
| 100 | assert reader.read_line()! == 'second line' |
| 101 | } |
| 102 | |
| 103 | fn test_from_string() { |
| 104 | mut reader := StringReader.new(source: 'test') |
| 105 | assert reader.read_all(false)! == 'test' |
| 106 | |
| 107 | if _ := reader.read_all(false) { |
| 108 | assert false, 'should return Eof' |
| 109 | } else { |
| 110 | assert err is io.Eof |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | fn test_read_from_source_read() { |
| 115 | source := 'line 1\nline 2\n' |
| 116 | mut reader := StringReader.new(source: source) |
| 117 | mut buf := []u8{len: 100} |
| 118 | read := reader.read(mut buf)! |
| 119 | assert read == source.len |
| 120 | assert buf[..read].bytestr() == source |
| 121 | if _ := reader.read(mut buf) { |
| 122 | assert false, 'should return io.Eof' |
| 123 | } else { |
| 124 | assert err is io.Eof |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | fn test_read_from_source_read_via_reader_interface() { |
| 129 | source := 'line 1\nline 2\n' |
| 130 | mut reader := StringReader.new(source: source) |
| 131 | mut buf := []u8{len: 100} |
| 132 | read := read_from_reader_interface(mut reader, mut buf)! |
| 133 | assert read == source.len |
| 134 | assert buf[..read].bytestr() == source |
| 135 | if _ := read_from_reader_interface(mut reader, mut buf) { |
| 136 | assert false, 'should return io.Eof' |
| 137 | } else { |
| 138 | assert err is io.Eof |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | fn test_from_string_read_byte_one_by_one() { |
| 143 | mut reader := StringReader.new(source: 'test') |
| 144 | assert reader.read_bytes(1)![0].ascii_str() == 't' |
| 145 | assert reader.read_bytes(1)![0].ascii_str() == 'e' |
| 146 | assert reader.read_bytes(1)![0].ascii_str() == 's' |
| 147 | assert reader.read_bytes(1)![0].ascii_str() == 't' |
| 148 | |
| 149 | if _ := reader.read_all(false) { |
| 150 | assert false, 'should return Eof' |
| 151 | } else { |
| 152 | assert err is io.Eof |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | fn test_from_string_and_reader() { |
| 157 | buf := Buf{ |
| 158 | bytes: 'buffer'.bytes() |
| 159 | } |
| 160 | |
| 161 | mut reader := StringReader.new(reader: buf, source: 'string') |
| 162 | |
| 163 | assert reader.read_all(false)! == 'stringbuffer' |
| 164 | } |
| 165 | |
| 166 | fn test_flush() { |
| 167 | mut reader := StringReader.new(source: 'flushed data') |
| 168 | |
| 169 | str := reader.flush() |
| 170 | assert str == 'flushed data' |
| 171 | |
| 172 | assert reader.offset == 0 |
| 173 | assert reader.builder.len == 0 |
| 174 | } |
| 175 | |
| 176 | fn test_fill_buffer_true() { |
| 177 | mut two := TwoByteReader{ |
| 178 | data: '12345' |
| 179 | } |
| 180 | mut reader := StringReader.new(reader: two) |
| 181 | assert reader.fill_buffer(true)! == 5 |
| 182 | assert reader.get_string() == '12345' |
| 183 | } |
| 184 | |
| 185 | fn test_fill_buffer_false() { |
| 186 | mut two := TwoByteReader{ |
| 187 | data: '12345' |
| 188 | } |
| 189 | mut reader := StringReader.new(reader: two) |
| 190 | assert reader.fill_buffer(false)! == 2 |
| 191 | assert reader.get_string() == '12' |
| 192 | } |
| 193 | |
| 194 | fn test_fill_buffer_until() { |
| 195 | mut two := TwoByteReader{ |
| 196 | data: '12345' |
| 197 | } |
| 198 | mut reader := StringReader.new(reader: two) |
| 199 | assert reader.fill_buffer_until(1)! == 1 |
| 200 | assert reader.builder.len == 1 |
| 201 | assert reader.fill_buffer_until(2)! == 2 |
| 202 | assert reader.builder.len == 3 |
| 203 | assert reader.fill_buffer_until(2)! == 2 |
| 204 | assert reader.builder.len == 5 |
| 205 | assert reader.get_string() == '12345' |
| 206 | } |
| 207 | |
| 208 | fn test_fill_buffer_until_one() { |
| 209 | mut two := TwoByteReader{ |
| 210 | data: '12345' |
| 211 | } |
| 212 | mut reader := StringReader.new(reader: two) |
| 213 | assert reader.fill_buffer_until(1)! == 1 |
| 214 | assert reader.builder.len == 1 |
| 215 | assert reader.fill_buffer_until(1)! == 1 |
| 216 | assert reader.builder.len == 2 |
| 217 | assert reader.fill_buffer_until(1)! == 1 |
| 218 | assert reader.builder.len == 3 |
| 219 | assert reader.fill_buffer_until(1)! == 1 |
| 220 | assert reader.builder.len == 4 |
| 221 | assert reader.fill_buffer_until(1)! == 1 |
| 222 | assert reader.builder.len == 5 |
| 223 | assert reader.get_string() == '12345' |
| 224 | } |
| 225 | |
| 226 | fn test_fill_buffer_until_many() { |
| 227 | mut two := TwoByteReader{ |
| 228 | data: '12345' |
| 229 | } |
| 230 | mut reader := StringReader.new(reader: two) |
| 231 | assert reader.fill_buffer_until(1)! == 1 |
| 232 | assert reader.builder.len == 1 |
| 233 | assert reader.fill_buffer_until(12)! == 4 |
| 234 | assert reader.builder.len == 5 |
| 235 | assert reader.fill_buffer_until(123) or { -1 } == -1 |
| 236 | assert reader.builder.len == 5 |
| 237 | assert reader.get_string() == '12345' |
| 238 | } |
| 239 | |
| 240 | fn test_read_all_bytes_false() { |
| 241 | mut two := TwoByteReader{ |
| 242 | data: '12345' |
| 243 | } |
| 244 | mut reader := StringReader.new(reader: two) |
| 245 | assert reader.read_all_bytes(false)! == [u8(49), 50] |
| 246 | assert reader.read_all_bytes(false)! == [u8(51), 52] |
| 247 | assert reader.read_all_bytes(false)! == [u8(53)] |
| 248 | } |
| 249 | |
| 250 | fn test_read_all_bytes_true() { |
| 251 | mut two := TwoByteReader{ |
| 252 | data: '12345' |
| 253 | } |
| 254 | mut reader := StringReader.new(reader: two) |
| 255 | assert reader.read_all_bytes(false)! == [u8(49), 50] |
| 256 | assert reader.read_all_bytes(true)! == [u8(51), 52, 53] |
| 257 | } |
| 258 | |
| 259 | fn test_read_all_false() { |
| 260 | mut two := TwoByteReader{ |
| 261 | data: '12345' |
| 262 | } |
| 263 | mut reader := StringReader.new(reader: two) |
| 264 | assert reader.read_all(false)! == '12' |
| 265 | assert reader.read_all(false)! == '34' |
| 266 | assert reader.read_all(false)! == '5' |
| 267 | } |
| 268 | |
| 269 | fn test_read_all_true() { |
| 270 | mut two := TwoByteReader{ |
| 271 | data: '12345' |
| 272 | } |
| 273 | mut reader := StringReader.new(reader: two) |
| 274 | assert reader.read_all(false)! == '12' |
| 275 | assert reader.read_all(true)! == '345' |
| 276 | } |
| 277 | |
| 278 | fn test_read_bytes_1() { |
| 279 | mut two := TwoByteReader{ |
| 280 | data: '12345' |
| 281 | } |
| 282 | mut reader := StringReader.new(reader: two) |
| 283 | assert reader.read_bytes(1)! == [u8(49)] |
| 284 | assert reader.read_bytes(2)! == [u8(50), 51] |
| 285 | assert reader.read_bytes(2)! == [u8(52), 53] |
| 286 | assert reader.read_bytes(2) or { [u8(255)] } == [u8(255)] |
| 287 | } |
| 288 | |
| 289 | fn test_read_bytes_many() { |
| 290 | mut two := TwoByteReader{ |
| 291 | data: '12345' |
| 292 | } |
| 293 | mut reader := StringReader.new(reader: two) |
| 294 | assert reader.read_bytes(1)! == [u8(49)] |
| 295 | assert reader.builder.len == 1 |
| 296 | assert reader.offset == 1 |
| 297 | assert reader.read_bytes(123)! == [u8(50), 51, 52, 53] |
| 298 | assert reader.builder.len == 5 |
| 299 | assert reader.offset == 5 |
| 300 | } |
| 301 | |
| 302 | fn test_read_string() { |
| 303 | mut two := TwoByteReader{ |
| 304 | data: '12345' |
| 305 | } |
| 306 | mut reader := StringReader.new(reader: two) |
| 307 | assert reader.read_string(1)! == '1' |
| 308 | assert reader.read_string(2)! == '23' |
| 309 | assert reader.read_string(3)! == '45' |
| 310 | } |
| 311 | |
| 312 | fn test_read() { |
| 313 | mut two := TwoByteReader{ |
| 314 | data: '12345' |
| 315 | } |
| 316 | mut reader := StringReader.new(reader: two) |
| 317 | mut o1 := []u8{len: 1} |
| 318 | mut o5 := []u8{len: 5} |
| 319 | mut res := reader.read(mut o1)! |
| 320 | assert res == 1 |
| 321 | assert o1[..res] == [u8(49)] |
| 322 | res = reader.read(mut o5)! |
| 323 | assert res == 4 |
| 324 | assert o5[..res] == [u8(50), 51, 52, 53] |
| 325 | } |
| 326 | |
| 327 | fn test_read_many() { |
| 328 | mut two := TwoByteReader{ |
| 329 | data: '12345' |
| 330 | } |
| 331 | mut reader := StringReader.new(reader: two) |
| 332 | mut o4 := []u8{len: 4} |
| 333 | mut res := reader.read(mut o4)! |
| 334 | assert res == 4 |
| 335 | assert o4[..res] == [u8(49), 50, 51, 52] |
| 336 | res = reader.read(mut o4)! |
| 337 | assert res == 1 |
| 338 | assert o4[..res] == [u8(53)] |
| 339 | res = reader.read(mut o4) or { -1 } |
| 340 | assert res == -1 |
| 341 | assert o4 == [u8(53), 50, 51, 52] |
| 342 | } |
| 343 | |
| 344 | fn test_read_line_2() { |
| 345 | mut two := TwoByteReader{ |
| 346 | data: '12345\n67890' |
| 347 | } |
| 348 | mut reader := StringReader.new(reader: two) |
| 349 | assert reader.read_line()! == '12345' |
| 350 | assert reader.read_line()! == '67890' |
| 351 | } |
| 352 | |
| 353 | fn test_read_line_3() { |
| 354 | mut two := TwoByteReader{ |
| 355 | data: '12345\t67890' |
| 356 | } |
| 357 | mut reader := StringReader.new(reader: two) |
| 358 | assert reader.read_line(delim: `\t`)! == '12345' |
| 359 | assert reader.read_line()! == '67890' |
| 360 | } |
| 361 | |
| 362 | fn test_read_line_4() { |
| 363 | mut two := TwoByteReader{ |
| 364 | data: '12345\t67890' |
| 365 | } |
| 366 | mut reader := StringReader.new(reader: two) |
| 367 | assert reader.read_line(delim: `\t`)! == '12345' |
| 368 | assert reader.read_line(delim: `\t`)! == '67890' |
| 369 | } |
| 370 | |
| 371 | fn test_read_line_5() { |
| 372 | mut two := TwoByteReader{ |
| 373 | data: '\n12345\n67890' |
| 374 | } |
| 375 | mut reader := StringReader.new(reader: two) |
| 376 | assert reader.read_line()! == '' |
| 377 | assert reader.read_line()! == '12345' |
| 378 | assert reader.read_line()! == '67890' |
| 379 | } |
| 380 | |
| 381 | fn test_read_line_6() { |
| 382 | mut two := TwoByteReader{ |
| 383 | data: '\r\n12345\r\n67890' |
| 384 | } |
| 385 | mut reader := StringReader.new(reader: two) |
| 386 | assert reader.read_line()! == '' |
| 387 | assert reader.read_line()! == '12345' |
| 388 | assert reader.read_line()! == '67890' |
| 389 | } |
| 390 | |
| 391 | fn test_read_line_7() { |
| 392 | mut two := TwoByteReader{ |
| 393 | data: '1234567890' |
| 394 | } |
| 395 | mut reader := StringReader.new(reader: two) |
| 396 | assert reader.read_line(delim: `6`)! == '12345' |
| 397 | assert reader.read_line(delim: `6`)! == '7890' |
| 398 | assert reader.read_line() or { '777' } == '777' |
| 399 | } |
| 400 | |
| 401 | fn test_read_line_8() { |
| 402 | mut two := TwoByteReader{ |
| 403 | data: '12345\r\n67890' |
| 404 | } |
| 405 | mut reader := StringReader.new(reader: two) |
| 406 | assert reader.read_bytes(6)! == [u8(49), 50, 51, 52, 53, 13] |
| 407 | reader.read_line()! // \n |
| 408 | assert reader.read_line()! == '67890' |
| 409 | } |
| 410 | |