net: restore back the blocking TcpConn.read_line() method for simplicity
parent
02965e753e
commit
81fd49642a
|
@ -35,7 +35,8 @@ pub fn (c TcpConn) close() ? {
|
|||
// write_ptr blocks and attempts to write all data
|
||||
pub fn (c TcpConn) write_ptr(b byteptr, len int) ? {
|
||||
$if trace_tcp ? {
|
||||
eprintln('>>> TcpConn.write_ptr | c.sock.handle: $c.sock.handle | b: ${ptr_str(b)} len: $len')
|
||||
eprintln('>>> TcpConn.write_ptr | c.sock.handle: $c.sock.handle | b: ${ptr_str(b)} len: $len |\n' +
|
||||
unsafe { b.vstring_with_len(len) })
|
||||
}
|
||||
unsafe {
|
||||
mut ptr_base := byteptr(b)
|
||||
|
@ -85,6 +86,9 @@ pub fn (c TcpConn) read_ptr(buf_ptr byteptr, len int) ?int {
|
|||
error_ewouldblock {
|
||||
c.wait_for_read() ?
|
||||
res = wrap_read_result(C.recv(c.sock.handle, buf_ptr, len, 0)) ?
|
||||
$if trace_tcp ? {
|
||||
eprintln('<<< TcpConn.read_ptr | c.sock.handle: $c.sock.handle | buf_ptr: ${ptr_str(buf_ptr)} len: $len | res: $res')
|
||||
}
|
||||
return socket_error(res)
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
module net
|
||||
|
||||
const (
|
||||
crlf = '\r\n'
|
||||
msg_peek = 0x02
|
||||
max_read = 400
|
||||
)
|
||||
|
||||
// read_line is a *simple*, *non customizable*, blocking line reader.
|
||||
// It will *always* return a line, ending with CRLF, or just '', on EOF.
|
||||
// NB: if you want more control over the buffer, please use a buffered IO
|
||||
// reader instead: `io.new_buffered_reader({reader: io.make_reader(con)})`
|
||||
pub fn (con TcpConn) read_line() string {
|
||||
mut buf := [max_read]byte{} // where C.recv will store the network data
|
||||
mut res := '' // The final result, including the ending \n.
|
||||
for {
|
||||
mut line := '' // The current line. Can be a partial without \n in it.
|
||||
n := C.recv(con.sock.handle, buf, max_read - 1, msg_peek | msg_nosignal)
|
||||
if n == -1 {
|
||||
return res
|
||||
}
|
||||
if n == 0 {
|
||||
return res
|
||||
}
|
||||
buf[n] = `\0`
|
||||
mut eol_idx := -1
|
||||
for i in 0 .. n {
|
||||
if int(buf[i]) == `\n` {
|
||||
eol_idx = i
|
||||
// Ensure that tos_clone(buf) later,
|
||||
// will return *only* the first line (including \n),
|
||||
// and ignore the rest
|
||||
buf[i + 1] = `\0`
|
||||
break
|
||||
}
|
||||
}
|
||||
bufbp := byteptr(buf)
|
||||
line = tos_clone(bufbp)
|
||||
if eol_idx > 0 {
|
||||
// At this point, we are sure that recv returned valid data,
|
||||
// that contains *at least* one line.
|
||||
// Ensure that the block till the first \n (including it)
|
||||
// is removed from the socket's receive queue, so that it does
|
||||
// not get read again.
|
||||
C.recv(con.sock.handle, buf, eol_idx + 1, msg_nosignal)
|
||||
res += line
|
||||
break
|
||||
}
|
||||
// recv returned a buffer without \n in it .
|
||||
C.recv(con.sock.handle, buf, n, msg_nosignal)
|
||||
res += line
|
||||
res += crlf
|
||||
break
|
||||
}
|
||||
return res
|
||||
}
|
Loading…
Reference in New Issue