mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
net: restore back the blocking TcpConn.read_line() method for simplicity
This commit is contained in:
parent
02965e753e
commit
81fd49642a
@ -35,7 +35,8 @@ pub fn (c TcpConn) close() ? {
|
|||||||
// write_ptr blocks and attempts to write all data
|
// write_ptr blocks and attempts to write all data
|
||||||
pub fn (c TcpConn) write_ptr(b byteptr, len int) ? {
|
pub fn (c TcpConn) write_ptr(b byteptr, len int) ? {
|
||||||
$if trace_tcp ? {
|
$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 {
|
unsafe {
|
||||||
mut ptr_base := byteptr(b)
|
mut ptr_base := byteptr(b)
|
||||||
@ -85,6 +86,9 @@ pub fn (c TcpConn) read_ptr(buf_ptr byteptr, len int) ?int {
|
|||||||
error_ewouldblock {
|
error_ewouldblock {
|
||||||
c.wait_for_read() ?
|
c.wait_for_read() ?
|
||||||
res = wrap_read_result(C.recv(c.sock.handle, buf_ptr, len, 0)) ?
|
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)
|
return socket_error(res)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
56
vlib/net/tcp_read_line.v
Normal file
56
vlib/net/tcp_read_line.v
Normal file
@ -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
Block a user