make socket_read()'s interface more like socket_read_line()'s
return a pointer into the internal buffer rather than copying into a user-supplied one. this permits zero-copy in future use cases.
This commit is contained in:
parent
6f15980cd9
commit
96b1e52802
|
@ -824,7 +824,8 @@ parse_imap_list( imap_store_t *ctx, char **sp, parse_list_state_t *sts )
|
||||||
{
|
{
|
||||||
list_t *cur, **curp;
|
list_t *cur, **curp;
|
||||||
char *s = *sp, *d, *p;
|
char *s = *sp, *d, *p;
|
||||||
int n, bytes;
|
int bytes;
|
||||||
|
uint n;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
assert( sts );
|
assert( sts );
|
||||||
|
@ -882,12 +883,14 @@ parse_imap_list( imap_store_t *ctx, char **sp, parse_list_state_t *sts )
|
||||||
s[cur->len] = 0;
|
s[cur->len] = 0;
|
||||||
|
|
||||||
getbytes:
|
getbytes:
|
||||||
n = socket_read( &ctx->conn, s, (uint)bytes );
|
if (!(p = socket_read( &ctx->conn, 1, (uint)bytes, &n )))
|
||||||
if (n < 0) {
|
goto postpone;
|
||||||
|
if (p == (void *)~0) {
|
||||||
badeof:
|
badeof:
|
||||||
sts->err = "unexpected EOF";
|
sts->err = "unexpected EOF";
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
memcpy( s, p, n );
|
||||||
bytes -= n;
|
bytes -= n;
|
||||||
if (bytes > 0)
|
if (bytes > 0)
|
||||||
goto postpone;
|
goto postpone;
|
||||||
|
|
34
src/socket.c
34
src/socket.c
|
@ -799,20 +799,30 @@ socket_expect_eof( conn_t *sock )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
char *
|
||||||
socket_read( conn_t *conn, char *buf, uint len )
|
socket_read( conn_t *conn, uint min_len, uint max_len, uint *out_len )
|
||||||
{
|
{
|
||||||
uint n = conn->bytes;
|
assert( min_len > 0 );
|
||||||
if (!n && conn->state == SCK_EOF)
|
assert( min_len <= sizeof(conn->buf) );
|
||||||
return -1;
|
assert( min_len <= max_len );
|
||||||
if (n > len)
|
|
||||||
n = len;
|
uint off = conn->offset;
|
||||||
memcpy( buf, conn->buf + conn->offset, n );
|
uint cnt = conn->bytes;
|
||||||
if (!(conn->bytes -= n))
|
if (cnt < min_len) {
|
||||||
|
if (conn->state == SCK_EOF)
|
||||||
|
return (void *)~0;
|
||||||
|
if (off + min_len > sizeof(conn->buf)) {
|
||||||
|
memmove( conn->buf, conn->buf + off, cnt );
|
||||||
conn->offset = 0;
|
conn->offset = 0;
|
||||||
else
|
}
|
||||||
conn->offset += n;
|
return NULL;
|
||||||
return (int)n;
|
}
|
||||||
|
uint n = (cnt < max_len) ? cnt : max_len;
|
||||||
|
cnt -= n;
|
||||||
|
conn->offset = cnt ? off + n : 0;
|
||||||
|
conn->bytes = cnt;
|
||||||
|
*out_len = n;
|
||||||
|
return conn->buf + off;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
|
|
@ -128,8 +128,9 @@ void socket_start_deflate( conn_t *conn );
|
||||||
void socket_close( conn_t *sock );
|
void socket_close( conn_t *sock );
|
||||||
void socket_expect_activity( conn_t *sock, int expect );
|
void socket_expect_activity( conn_t *sock, int expect );
|
||||||
void socket_expect_eof( conn_t *sock );
|
void socket_expect_eof( conn_t *sock );
|
||||||
int socket_read( conn_t *sock, char *buf, uint len ); /* never waits */
|
// Don't free return values. These functions never wait.
|
||||||
char *socket_read_line( conn_t *sock ); /* don't free return value; never waits */
|
char *socket_read( conn_t *conn, uint min_len, uint max_len, uint *out_len );
|
||||||
|
char *socket_read_line( conn_t *conn );
|
||||||
typedef enum { KeepOwn = 0, GiveOwn } ownership_t;
|
typedef enum { KeepOwn = 0, GiveOwn } ownership_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user