module string_reader import io struct Buf { pub: bytes []u8 mut: i int } struct TwoByteReader { mut: data string pos int } fn (mut b Buf) read(mut buf []u8) !int { if !(b.i < b.bytes.len) { return io.Eof{} } n := copy(mut buf, b.bytes[b.i..]) b.i += n return n } fn (mut r TwoByteReader) read(mut buf []u8) !int { if r.pos >= r.data.len { return io.Eof{} } min := int_min(int_min(r.data.len - r.pos, 2), buf.len) for i in 0 .. min { buf[i] = r.data[r.pos] r.pos++ } return min } fn read_from_reader_interface(mut r io.Reader, mut buf []u8) !int { return r.read(mut buf) } fn test_read_all() { mut reader := StringReader.new() if _ := reader.read_all(false) { assert false, 'should return io.Eof' } else { assert err is io.Eof } contents := 'test string' buf := Buf{ bytes: contents.bytes() } reader = StringReader.new(reader: buf) data := reader.read_all(false)! assert data == contents } fn test_read_bytes() { mut reader := StringReader.new() if _ := reader.read_bytes(4) { assert false, 'should return io.Eof' } else { assert err.msg() == 'reader is not set' } buf := Buf{ bytes: '12345678'.bytes() } reader = StringReader.new(reader: buf) mut data := reader.read_bytes(4)! assert data == buf.bytes[..4] data = reader.read_bytes(4)! assert data == buf.bytes[4..8] } fn test_read_line() { mut reader := StringReader.new() if _ := reader.read_line() { assert false, 'should return io.Eof' } else { assert err is io.Eof } buf := Buf{ bytes: 'first line\r\nsecond line\n'.bytes() } reader = StringReader.new(reader: buf) assert reader.read_line()! == 'first line' assert reader.read_line()! == 'second line' } fn test_from_string() { mut reader := StringReader.new(source: 'test') assert reader.read_all(false)! == 'test' if _ := reader.read_all(false) { assert false, 'should return Eof' } else { assert err is io.Eof } } fn test_read_from_source_read() { source := 'line 1\nline 2\n' mut reader := StringReader.new(source: source) mut buf := []u8{len: 100} read := reader.read(mut buf)! assert read == source.len assert buf[..read].bytestr() == source if _ := reader.read(mut buf) { assert false, 'should return io.Eof' } else { assert err is io.Eof } } fn test_read_from_source_read_via_reader_interface() { source := 'line 1\nline 2\n' mut reader := StringReader.new(source: source) mut buf := []u8{len: 100} read := read_from_reader_interface(mut reader, mut buf)! assert read == source.len assert buf[..read].bytestr() == source if _ := read_from_reader_interface(mut reader, mut buf) { assert false, 'should return io.Eof' } else { assert err is io.Eof } } fn test_from_string_read_byte_one_by_one() { mut reader := StringReader.new(source: 'test') assert reader.read_bytes(1)![0].ascii_str() == 't' assert reader.read_bytes(1)![0].ascii_str() == 'e' assert reader.read_bytes(1)![0].ascii_str() == 's' assert reader.read_bytes(1)![0].ascii_str() == 't' if _ := reader.read_all(false) { assert false, 'should return Eof' } else { assert err is io.Eof } } fn test_from_string_and_reader() { buf := Buf{ bytes: 'buffer'.bytes() } mut reader := StringReader.new(reader: buf, source: 'string') assert reader.read_all(false)! == 'stringbuffer' } fn test_flush() { mut reader := StringReader.new(source: 'flushed data') str := reader.flush() assert str == 'flushed data' assert reader.offset == 0 assert reader.builder.len == 0 } fn test_fill_buffer_true() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.fill_buffer(true)! == 5 assert reader.get_string() == '12345' } fn test_fill_buffer_false() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.fill_buffer(false)! == 2 assert reader.get_string() == '12' } fn test_fill_buffer_until() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.fill_buffer_until(1)! == 1 assert reader.builder.len == 1 assert reader.fill_buffer_until(2)! == 2 assert reader.builder.len == 3 assert reader.fill_buffer_until(2)! == 2 assert reader.builder.len == 5 assert reader.get_string() == '12345' } fn test_fill_buffer_until_one() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.fill_buffer_until(1)! == 1 assert reader.builder.len == 1 assert reader.fill_buffer_until(1)! == 1 assert reader.builder.len == 2 assert reader.fill_buffer_until(1)! == 1 assert reader.builder.len == 3 assert reader.fill_buffer_until(1)! == 1 assert reader.builder.len == 4 assert reader.fill_buffer_until(1)! == 1 assert reader.builder.len == 5 assert reader.get_string() == '12345' } fn test_fill_buffer_until_many() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.fill_buffer_until(1)! == 1 assert reader.builder.len == 1 assert reader.fill_buffer_until(12)! == 4 assert reader.builder.len == 5 assert reader.fill_buffer_until(123) or { -1 } == -1 assert reader.builder.len == 5 assert reader.get_string() == '12345' } fn test_read_all_bytes_false() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.read_all_bytes(false)! == [u8(49), 50] assert reader.read_all_bytes(false)! == [u8(51), 52] assert reader.read_all_bytes(false)! == [u8(53)] } fn test_read_all_bytes_true() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.read_all_bytes(false)! == [u8(49), 50] assert reader.read_all_bytes(true)! == [u8(51), 52, 53] } fn test_read_all_false() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.read_all(false)! == '12' assert reader.read_all(false)! == '34' assert reader.read_all(false)! == '5' } fn test_read_all_true() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.read_all(false)! == '12' assert reader.read_all(true)! == '345' } fn test_read_bytes_1() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.read_bytes(1)! == [u8(49)] assert reader.read_bytes(2)! == [u8(50), 51] assert reader.read_bytes(2)! == [u8(52), 53] assert reader.read_bytes(2) or { [u8(255)] } == [u8(255)] } fn test_read_bytes_many() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.read_bytes(1)! == [u8(49)] assert reader.builder.len == 1 assert reader.offset == 1 assert reader.read_bytes(123)! == [u8(50), 51, 52, 53] assert reader.builder.len == 5 assert reader.offset == 5 } fn test_read_string() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) assert reader.read_string(1)! == '1' assert reader.read_string(2)! == '23' assert reader.read_string(3)! == '45' } fn test_read() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) mut o1 := []u8{len: 1} mut o5 := []u8{len: 5} mut res := reader.read(mut o1)! assert res == 1 assert o1[..res] == [u8(49)] res = reader.read(mut o5)! assert res == 4 assert o5[..res] == [u8(50), 51, 52, 53] } fn test_read_many() { mut two := TwoByteReader{ data: '12345' } mut reader := StringReader.new(reader: two) mut o4 := []u8{len: 4} mut res := reader.read(mut o4)! assert res == 4 assert o4[..res] == [u8(49), 50, 51, 52] res = reader.read(mut o4)! assert res == 1 assert o4[..res] == [u8(53)] res = reader.read(mut o4) or { -1 } assert res == -1 assert o4 == [u8(53), 50, 51, 52] } fn test_read_line_2() { mut two := TwoByteReader{ data: '12345\n67890' } mut reader := StringReader.new(reader: two) assert reader.read_line()! == '12345' assert reader.read_line()! == '67890' } fn test_read_line_3() { mut two := TwoByteReader{ data: '12345\t67890' } mut reader := StringReader.new(reader: two) assert reader.read_line(delim: `\t`)! == '12345' assert reader.read_line()! == '67890' } fn test_read_line_4() { mut two := TwoByteReader{ data: '12345\t67890' } mut reader := StringReader.new(reader: two) assert reader.read_line(delim: `\t`)! == '12345' assert reader.read_line(delim: `\t`)! == '67890' } fn test_read_line_5() { mut two := TwoByteReader{ data: '\n12345\n67890' } mut reader := StringReader.new(reader: two) assert reader.read_line()! == '' assert reader.read_line()! == '12345' assert reader.read_line()! == '67890' } fn test_read_line_6() { mut two := TwoByteReader{ data: '\r\n12345\r\n67890' } mut reader := StringReader.new(reader: two) assert reader.read_line()! == '' assert reader.read_line()! == '12345' assert reader.read_line()! == '67890' } fn test_read_line_7() { mut two := TwoByteReader{ data: '1234567890' } mut reader := StringReader.new(reader: two) assert reader.read_line(delim: `6`)! == '12345' assert reader.read_line(delim: `6`)! == '7890' assert reader.read_line() or { '777' } == '777' } fn test_read_line_8() { mut two := TwoByteReader{ data: '12345\r\n67890' } mut reader := StringReader.new(reader: two) assert reader.read_bytes(6)! == [u8(49), 50, 51, 52, 53, 13] reader.read_line()! // \n assert reader.read_line()! == '67890' }