io: input/output streams (#6078)

pull/6084/head
Louis Schmieder 2020-08-09 04:12:29 +02:00 committed by GitHub
parent 4e8fe9b1a8
commit 97fec78b40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 605 additions and 0 deletions

View File

@ -0,0 +1,181 @@
import net
import io
struct Test {
a int
b f32
c string
}
fn setup() (net.Socket, net.Socket, net.Socket) {
server := net.listen(0) or { panic(err) }
server_port := server.get_port()
client := net.dial('127.0.0.1', server_port) or { panic(err) }
socket := server.accept() or { panic(err) }
return server, client, socket
}
fn test_arrays() {
_, c, s := setup()
mut nos := io.new_net_output_stream(s)
mut nis := io.new_net_input_stream(c)
//bytes
a := [byte(76), 7, 43, 5]
nos.write_bytes(a) or { assert false }
c_a := nis.read_bytes(4)
assert a == c_a
//u16s
b := [u16(546), 3434, 33]
nos.write_u16s(b) or { assert false }
c_b := nis.read_u16s(3)
assert b == c_b
//u32s
d := [u32(10), 34324, 454, 34, 352]
nos.write_u32s(d) or { assert false }
c_d := nis.read_u32s(5)
assert d == c_d
//u64s
e := [u64(32542), 23213, 23244353, 324534534]
nos.write_u64s(e) or { assert false }
c_e := nis.read_u64s(4)
assert e == c_e
//i8s
f := [i8(20), 40, 5, 10]
nos.write_i8s(f) or { assert false }
c_f := nis.read_i8s(4)
assert f == c_f
//i16s
g := [i16(3434), 3242, 655, 445, 23]
nos.write_i16s(g) or { assert false }
c_g := nis.read_i16s(5)
assert g == c_g
//i32s
h := [342, 32424, 565, 343, 7676, 34]
nos.write_ints(h) or { assert false }
c_h := nis.read_ints(6)
assert h == c_h
//i64s
i := [i64(354345), 45435564, 54645654, 3242342]
nos.write_i64s(i) or { assert false }
c_i := nis.read_i64s(4)
assert i == c_i
}
fn test_primitives() {
_, c, s := setup()
mut nos := io.new_net_output_stream(s)
mut nis := io.new_net_input_stream(c)
// bytes
a := byte(45)
nos.write_byte(a) or { assert false }
c_a := nis.read_byte()
assert a == c_a
// u16
b := u16(345)
nos.write_u16(b) or { assert false }
c_b := nis.read_u16()
assert b == c_b
// u32
d := u32(353453)
nos.write_u32(d) or { assert false }
c_d := nis.read_u32()
assert d == c_d
// u64
e := u64(43645645654)
nos.write_u64(e) or { assert false }
c_e := nis.read_u64()
assert e == c_e
// i8
f := i8(43)
nos.write_i8(f) or { assert false }
c_f := nis.read_i8()
assert f == c_f
// i16
g := i16(676)
nos.write_i16(g) or { assert false }
c_g := nis.read_i16()
assert g == c_g
// int
h := 4543565
nos.write_int(h) or { assert false }
c_h := nis.read_int()
assert h == c_h
// i64
i := i64(4343654654654)
nos.write_i64(i) or { assert false }
c_i := nis.read_i64()
assert i == c_i
}
fn test_floats() {
_, c, s := setup()
mut nos := io.new_net_output_stream(s)
mut nis := io.new_net_input_stream(c)
a := f32(7.5)
nos.write_f32(a) or { assert false }
c_a := nis.read_f32()
assert a == c_a
b := f64(43587349857834579834.45435435)
nos.write_f64(b) or { assert false }
c_b := nis.read_f64()
assert b == c_b
d := [f32(7.3), 3.45, 546.3, 4545.3]
nos.write_f32s(d) or { assert false }
c_d := nis.read_f32s(4)
assert d == c_d
e := [f64(345324324.3242342), 3243242.342, 344564.343242423, 43543.43534, 34234.34324]
nos.write_f64s(e) or { assert false }
c_e := nis.read_f64s(5)
assert e == c_e
}
fn test_string() {
_, c, s := setup()
mut nos := io.new_net_output_stream(s)
mut nis := io.new_net_input_stream(c)
a := 'hello'
nos.write_string(a) or { assert false }
c_a := nis.read_string(5)
assert a == c_a
}
fn test_struct() {
_, c, s := setup()
mut nos := io.new_net_output_stream(s)
mut nis := io.new_net_input_stream(c)
a := Test{
a: 1
b: 2.0
c: 'test'
}
nos.write_struct(a, sizeof(Test)) or { assert false }
got := &Test(nis.read_struct(sizeof(Test)))
de_ref := *got
assert a.a == de_ref.a && a.b == de_ref.b && a.c == de_ref.c
}

View File

@ -0,0 +1,188 @@
module io
import net
import encoding.binary
struct NetInputStream {
mut:
sock &net.Socket
}
pub fn new_net_input_stream(sock &net.Socket) &NetInputStream {
return &NetInputStream{
sock: sock
}
}
pub fn (mut nis NetInputStream) read_int() int {
return int(binary.big_endian_u32(nis.read_bytes(sizeof(int))))
}
pub fn (mut nis NetInputStream) read_ints(l u32) []int {
bytes := nis.read_bytes(sizeof(int) * l)
mut ints := []int{}
for i in 0 .. l {
offs := int(u32(i) * sizeof(int))
b := bytes[offs..int(u32(offs) + sizeof(int))]
ints << int(binary.big_endian_u32(b))
}
return ints
}
pub fn (mut nis NetInputStream) read_i8() i8 {
return i8(nis.read_byte())
}
pub fn (mut nis NetInputStream) read_i8s(l u32) []i8 {
bytes := nis.read_bytes(sizeof(i8) * l)
mut i8s := []i8{}
for i in 0 .. l {
i8s << i8(bytes[i])
}
return i8s
}
pub fn (mut nis NetInputStream) read_i16() i16 {
return i16(binary.big_endian_u16(nis.read_bytes(sizeof(i16))))
}
pub fn (mut nis NetInputStream) read_i16s(l u32) []i16 {
bytes := nis.read_bytes(sizeof(i16) * l)
mut i16s := []i16{}
for i in 0 .. l {
offs := int(u32(i) * sizeof(i16))
b := bytes[offs..int(u32(offs) + sizeof(i16))]
i16s << i16(binary.big_endian_u16(b))
}
return i16s
}
pub fn (mut nis NetInputStream) read_i64() i64 {
return i64(binary.big_endian_u64(nis.read_bytes(sizeof(i64))))
}
pub fn (mut nis NetInputStream) read_i64s(l u32) []i64 {
bytes := nis.read_bytes(sizeof(i64) * l)
mut i64s := []i64{}
for i in 0 .. l {
offs := int(u32(i) * sizeof(i64))
b := bytes[offs..int(u32(offs) + sizeof(i64))]
i64s << i64(binary.big_endian_u64(b))
}
return i64s
}
pub fn (mut nis NetInputStream) read_byte() byte {
ptr, _ := nis.sock.recv(int(sizeof(byte)))
unsafe {
return ptr[0]
}
}
pub fn (mut nis NetInputStream) read_bytes(l u32) []byte {
mut bytes := []byte{len: int(l), cap: int(l)}
for i in 0..l {
bytes[i] = nis.read_byte()
}
return bytes
}
pub fn (mut nis NetInputStream) read_u16() u16 {
return binary.big_endian_u16(nis.read_bytes(sizeof(u16)))
}
pub fn (mut nis NetInputStream) read_u16s(l u32) []u16 {
bytes := nis.read_bytes(sizeof(u16) * l)
mut u16s := []u16{}
for i in 0 .. l {
offs := int(u32(i) * sizeof(u16))
b := bytes[offs..int(u32(offs) + sizeof(u16))]
u16s << binary.big_endian_u16(b)
}
return u16s
}
pub fn (mut nis NetInputStream) read_u32() u32 {
return binary.big_endian_u32(nis.read_bytes(sizeof(u32)))
}
pub fn (mut nis NetInputStream) read_u32s(l u32) []u32 {
bytes := nis.read_bytes(sizeof(u32) * l)
mut u32s := []u32{}
for i in 0 .. l {
offs := int(u32(i) * sizeof(u32))
b := bytes[offs..int(u32(offs) + sizeof(u32))]
u32s << binary.big_endian_u32(b)
}
return u32s
}
pub fn (mut nis NetInputStream) read_u64() u64 {
return binary.big_endian_u64(nis.read_bytes(sizeof(u64)))
}
pub fn (mut nis NetInputStream) read_u64s(l u32) []u64 {
bytes := nis.read_bytes(sizeof(u64) * l)
mut u64s := []u64{}
for i in 0 .. l {
offs := int(u32(i) * sizeof(u64))
b := bytes[offs..int(u32(offs) + sizeof(u64))]
u64s << binary.big_endian_u64(b)
}
return u64s
}
pub fn (mut nis NetInputStream) read_f32() f32 {
bytes := nis.read_bytes(sizeof(f32))
f := &f32(bytes.data)
return *f
}
pub fn (mut nis NetInputStream) read_f32s(l u32) []f32 {
bytes := nis.read_bytes(sizeof(f32) * l)
mut f32s := []f32{}
for i in 0 .. l {
offs := int(u32(i) * sizeof(f32))
b := bytes[offs..int(u32(offs) + sizeof(f32))]
f := &f32(b.data)
unsafe {
f32s << *f
}
}
return f32s
}
pub fn (mut nis NetInputStream) read_f64() f64 {
bytes := nis.read_bytes(sizeof(f64))
f := &f64(bytes.data)
return *f
}
pub fn (mut nis NetInputStream) read_f64s(l u32) []f64 {
bytes := nis.read_bytes(sizeof(f64) * l)
mut f64s := []f64{}
for i in 0 .. l {
offs := int(u32(i) * sizeof(f64))
b := bytes[offs..int(u32(offs) + sizeof(f64))]
f := &f64(b.data)
unsafe {
f64s << *f
}
}
return f64s
}
pub fn (mut nis NetInputStream) read_string(l u32) string {
bytes := nis.read_bytes(l)
return tos(bytes.data, bytes.len)
}
pub fn (mut nis NetInputStream) skip(l u32) {
nis.read_bytes(l)
}
// TODO make it generic
pub fn (mut nis NetInputStream) read_struct(l u32) voidptr {
return voidptr(nis.read_bytes(l).data)
}

View File

@ -0,0 +1,184 @@
module io
import net
import encoding.binary
struct NetOutputStream {
mut:
sock &net.Socket
}
pub fn new_net_output_stream(sock &net.Socket) &NetOutputStream {
return &NetOutputStream{
sock: sock
}
}
pub fn (mut nos NetOutputStream) write_int(d int) ? {
mut bytes := []byte{len: int(sizeof(int))}
binary.big_endian_put_u32(mut bytes, u32(d))
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_ints(d []int) ? {
mut bytes := []byte{}
for u in d {
mut tmp := []byte{len: int(sizeof(int))}
binary.big_endian_put_u32(mut tmp, u32(u))
bytes << tmp
}
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_i8(d i8) ? {
nos.sock.send([byte(d)].data, int(sizeof(i8)))?
}
pub fn (mut nos NetOutputStream) write_i8s(d []i8) ? {
nos.sock.send(d.data, int(sizeof(i8) * u32(d.len)))?
}
pub fn (mut nos NetOutputStream) write_i16(d i16) ? {
mut bytes := []byte{len: int(sizeof(i16))}
binary.big_endian_put_u16(mut bytes, u16(d))
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_i16s(d []i16) ? {
mut bytes := []byte{}
for u in d {
mut tmp := []byte{len: int(sizeof(i16))}
binary.big_endian_put_u16(mut tmp, u16(u))
bytes << tmp
}
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_i64(d i64) ? {
mut bytes := []byte{len: int(sizeof(i64))}
binary.big_endian_put_u64(mut bytes, u64(d))
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_i64s(d []i64) ? {
mut bytes := []byte{}
for u in d {
mut tmp := []byte{len: int(sizeof(i64))}
binary.big_endian_put_u64(mut tmp, u64(u))
bytes << tmp
}
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_byte(d byte) ? {
nos.sock.send([d].data, int(sizeof(byte)))?
}
pub fn (mut nos NetOutputStream) write_bytes(d []byte) ? {
nos.sock.send(d.data, int(sizeof(byte) * u32(d.len)))?
}
pub fn (mut nos NetOutputStream) write_u16(d u16) ? {
mut bytes := []byte{len: int(sizeof(u16))}
binary.big_endian_put_u16(mut bytes, d)
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_u16s(d []u16) ? {
mut bytes := []byte{}
for u in d {
mut tmp := []byte{len: int(sizeof(u16))}
binary.big_endian_put_u16(mut tmp, u)
bytes << tmp
}
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_u32(d u32) ? {
mut bytes := []byte{len: int(sizeof(u32))}
binary.big_endian_put_u32(mut bytes, d)
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_u32s(d []u32) ? {
mut bytes := []byte{}
for u in d {
mut tmp := []byte{len: int(sizeof(u32))}
binary.big_endian_put_u32(mut tmp, u)
bytes << tmp
}
nos.sock.send(bytes.data, int(sizeof(u32) * u32(d.len)))?
}
pub fn (mut nos NetOutputStream) write_u64(d u64) ? {
mut bytes := []byte{len: int(sizeof(u64))}
binary.big_endian_put_u64(mut bytes, d)
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_u64s(d []u64) ? {
mut bytes := []byte{}
for u in d {
mut tmp := []byte{len: int(sizeof(u64))}
binary.big_endian_put_u64(mut tmp, u)
bytes << tmp
}
nos.sock.send(bytes.data, int(sizeof(u64) * u32(d.len)))?
}
pub fn (mut nos NetOutputStream) write_f32(d f32) ? {
pb := &byte(&d)
mut bytes := []byte{len: int(sizeof(f32))}
unsafe {
for i in 0..bytes.len {
bytes[i] = pb[i]
}
}
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_f32s(d []f32) ? {
mut bytes := []byte{}
for f in d {
pb := &byte(&f)
unsafe {
for i in 0..int(sizeof(f32)) {
bytes << pb[i]
}
}
}
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_f64(d f64) ? {
pb := &byte(&d)
mut bytes := []byte{len: int(sizeof(f64))}
unsafe {
for i in 0..bytes.len {
bytes[i] = pb[i]
}
}
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_f64s(d []f64) ? {
mut bytes := []byte{}
for f in d {
pb := &byte(&f)
unsafe {
for i in 0..int(sizeof(f64)) {
bytes << pb[i]
}
}
}
nos.sock.send(bytes.data, bytes.len)?
}
pub fn (mut nos NetOutputStream) write_string(d string) ? {
nos.write_bytes(d.bytes())?
}
// TODO make it generic
pub fn (mut nos NetOutputStream) write_struct(d voidptr, l u32) ? {
nos.sock.send(byteptr(d), int(l))?
}

52
vlib/io/stream.v 100644
View File

@ -0,0 +1,52 @@
module io
pub interface InputStream {
read_int() int
read_ints(l u32) []int
read_i8() i8
read_i8s(l u32) []i8
read_i16() i16
read_i16s(l u32) []i16
read_i64() i64
read_i64s(l u32) []i64
read_byte() byte
read_bytes(l u32) []byte
read_u16() u16
read_u16s(l u32) []u16
read_u32() u32
read_u32s(l u32) []u32
read_u64() u64
read_u64s(l u32) []u64
read_f32() f32
read_f32s(l u32) []f32
read_f64() f64
read_f64s(l u32) []f64
read_string(l u32)
skip(l u32)
read_struct(l u32) voidptr
}
pub interface OutputStream {
write_int(d int) ?
write_ints(d []int) ?
write_i8(d i8) ?
write_i8s(d []i8) ?
write_i16(d i16) ?
write_i16s(d []i16) ?
write_i64(d i64) ?
write_i64s(d []i64) ?
write_byte(d byte) ?
write_bytes(d []byte) ?
write_u16(d u16) ?
write_u16s(d []u16) ?
write_u32(d u32) ?
write_u32s(d []u32) ?
write_u64(d u64) ?
write_u64s(d []u64) ?
write_f32(d f32) ?
write_f32s(d []f32) ?
write_f64(d f64) ?
write_f64s(d []f64) ?
write_string(d string) ?
write_struct(d voidptr, l u32) ?
}