mg_iobuf_append -> mg_iobuf_add

This commit is contained in:
Sergey Lyubka 2021-08-28 08:08:54 +01:00
parent 913e730ec2
commit 477e48bf54
9 changed files with 67 additions and 52 deletions

View File

@ -603,21 +603,20 @@ Free memory pointed by `io->buf` and set to NULL. Both `size` and `len` are set
to 0.
### mg\_iobuf\_append()
### mg\_iobuf\_add()
```c
size_t mg_iobuf_append(struct mg_iobuf *io, const void *data, size_t data_size, size_t granularity);
size_t mg_iobuf_add(struct mg_iobuf *io, size_t offset, const void *buf, size_t len, size_t granularity);
```
Append `data` bytes of size `data_size` to the end of the buffer. The buffer
is expanded if `data_size` is greater than `io->size - io->len`. If that
happens, the `io->buf` can change. The resulting `io->size` is always
set to the `granularity` byte boundary. Example:
Insert data buffer `buf`, `len` at offset `offset`. The iobuf gets
is expanded if required. The resulting `io->size` is always
aligned to the `granularity` byte boundary. Example:
```c
struct mg_iobuf io;
mg_iobuf_init(&io, 0); // Empty buffer
mg_iobuf_append(&io, "hi", 2, 1024); // io->len is 2, io->size is 1024
mg_iobuf_init(&io, 0); // Empty buffer
mg_iobuf_add(&io, 0, "hi", 2, 512); // io->len is 2, io->size is 512
```
### mg\_iobuf\_del()

View File

@ -1762,8 +1762,8 @@ int mg_iobuf_init(struct mg_iobuf *io, size_t size) {
return mg_iobuf_resize(io, size);
}
size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
size_t chunk_size) {
size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf,
size_t len, size_t chunk_size) {
size_t new_size = io->len + len;
if (new_size > io->size) {
new_size += chunk_size; // Make sure that io->size
@ -1771,7 +1771,9 @@ size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
mg_iobuf_resize(io, new_size); // Attempt to realloc
if (new_size != io->size) len = 0; // Realloc failure, append nothing
}
if (buf != NULL) memmove(io->buf + io->len, buf, len);
if (ofs < io->len) memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs);
if (buf != NULL) memmove(io->buf + ofs, buf, len);
if (ofs > io->len) io->len += ofs - io->len;
io->len += len;
return len;
}
@ -2935,7 +2937,7 @@ static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
return c->is_udp ? mg_sock_send(c, buf, len) > 0
: mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
: mg_iobuf_add(&c->send, c->send.len, buf, len, MG_IO_SIZE);
}
static void mg_set_non_blocking_mode(SOCKET fd) {
@ -3434,7 +3436,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
if (depth < MG_MAX_SSI_DEPTH &&
(data = mg_ssi(tmp, root, depth + 1)) != NULL) {
mg_iobuf_append(&b, data, strlen(data), align);
mg_iobuf_add(&b, b.len, data, strlen(data), align);
free(data);
} else {
LOG(LL_ERROR, ("%s: file=%s error or too deep", path, arg));
@ -3444,7 +3446,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
if (depth < MG_MAX_SSI_DEPTH &&
(data = mg_ssi(tmp, root, depth + 1)) != NULL) {
mg_iobuf_append(&b, data, strlen(data), align);
mg_iobuf_add(&b, b.len, data, strlen(data), align);
free(data);
} else {
LOG(LL_ERROR, ("%s: virtual=%s error or too deep", path, arg));
@ -3452,13 +3454,13 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
} else {
// Unknown SSI tag
LOG(LL_INFO, ("Unknown SSI tag: %.*s", (int) len, buf));
mg_iobuf_append(&b, buf, len, align);
mg_iobuf_add(&b, b.len, buf, len, align);
}
intag = 0;
len = 0;
} else if (ch == '<') {
intag = 1;
if (len > 0) mg_iobuf_append(&b, buf, len, align);
if (len > 0) mg_iobuf_add(&b, b.len, buf, len, align);
len = 0;
buf[len++] = (char) (ch & 0xff);
} else if (intag) {
@ -3472,13 +3474,13 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
} else {
buf[len++] = (char) (ch & 0xff);
if (len >= sizeof(buf)) {
mg_iobuf_append(&b, buf, len, align);
mg_iobuf_add(&b, b.len, buf, len, align);
len = 0;
}
}
}
if (len > 0) mg_iobuf_append(&b, buf, len, align);
if (b.len > 0) mg_iobuf_append(&b, "", 1, align); // nul-terminate
if (len > 0) mg_iobuf_add(&b, b.len, buf, len, align);
if (b.len > 0) mg_iobuf_add(&b, b.len, "", 1, align); // nul-terminate
fclose(fp);
}
(void) depth;
@ -4749,11 +4751,11 @@ size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
size_t header_len = mkhdr(len, op, c->is_client, header);
// NOTE: order of operations is important!
mg_iobuf_append(&c->send, NULL, header_len, MG_IO_SIZE); // Add header space
p = &c->send.buf[c->send.len - len]; // p points to data
memmove(p, p - header_len, len); // Shift data
memcpy(p - header_len, header, header_len); // Prepend header
mg_ws_mask(c, len); // Mask data
mg_iobuf_add(&c->send, c->send.len, NULL, header_len, MG_IO_SIZE);
p = &c->send.buf[c->send.len - len]; // p points to data
memmove(p, p - header_len, len); // Shift data
memcpy(p - header_len, header, header_len); // Prepend header
mg_ws_mask(c, len); // Mask data
return c->send.len;
}

View File

@ -628,14 +628,15 @@ const char *mg_url_uri(const char *url);
#include <stddef.h>
struct mg_iobuf {
unsigned char *buf;
size_t size, len;
unsigned char *buf; // Data
size_t size; // Total size available
size_t len; // Current number of bytes
};
int mg_iobuf_init(struct mg_iobuf *, size_t);
int mg_iobuf_resize(struct mg_iobuf *, size_t);
void mg_iobuf_free(struct mg_iobuf *);
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t, size_t);
size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);
int mg_base64_update(unsigned char p, char *to, int len);

View File

@ -42,8 +42,8 @@ int mg_iobuf_init(struct mg_iobuf *io, size_t size) {
return mg_iobuf_resize(io, size);
}
size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
size_t chunk_size) {
size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf,
size_t len, size_t chunk_size) {
size_t new_size = io->len + len;
if (new_size > io->size) {
new_size += chunk_size; // Make sure that io->size
@ -51,7 +51,9 @@ size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len,
mg_iobuf_resize(io, new_size); // Attempt to realloc
if (new_size != io->size) len = 0; // Realloc failure, append nothing
}
if (buf != NULL) memmove(io->buf + io->len, buf, len);
if (ofs < io->len) memmove(io->buf + ofs + len, io->buf + ofs, io->len - ofs);
if (buf != NULL) memmove(io->buf + ofs, buf, len);
if (ofs > io->len) io->len += ofs - io->len;
io->len += len;
return len;
}

View File

@ -3,12 +3,13 @@
#include <stddef.h>
struct mg_iobuf {
unsigned char *buf;
size_t size, len;
unsigned char *buf; // Data
size_t size; // Total size available
size_t len; // Current number of bytes
};
int mg_iobuf_init(struct mg_iobuf *, size_t);
int mg_iobuf_resize(struct mg_iobuf *, size_t);
void mg_iobuf_free(struct mg_iobuf *);
size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t);
size_t mg_iobuf_add(struct mg_iobuf *, size_t, const void *, size_t, size_t);
size_t mg_iobuf_del(struct mg_iobuf *, size_t ofs, size_t len);

View File

@ -107,7 +107,7 @@ static long mg_sock_send(struct mg_connection *c, const void *buf, size_t len) {
bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
return c->is_udp ? mg_sock_send(c, buf, len) > 0
: mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE);
: mg_iobuf_add(&c->send, c->send.len, buf, len, MG_IO_SIZE);
}
static void mg_set_non_blocking_mode(SOCKET fd) {

View File

@ -24,7 +24,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
if (depth < MG_MAX_SSI_DEPTH &&
(data = mg_ssi(tmp, root, depth + 1)) != NULL) {
mg_iobuf_append(&b, data, strlen(data), align);
mg_iobuf_add(&b, b.len, data, strlen(data), align);
free(data);
} else {
LOG(LL_ERROR, ("%s: file=%s error or too deep", path, arg));
@ -34,7 +34,7 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
if (depth < MG_MAX_SSI_DEPTH &&
(data = mg_ssi(tmp, root, depth + 1)) != NULL) {
mg_iobuf_append(&b, data, strlen(data), align);
mg_iobuf_add(&b, b.len, data, strlen(data), align);
free(data);
} else {
LOG(LL_ERROR, ("%s: virtual=%s error or too deep", path, arg));
@ -42,13 +42,13 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
} else {
// Unknown SSI tag
LOG(LL_INFO, ("Unknown SSI tag: %.*s", (int) len, buf));
mg_iobuf_append(&b, buf, len, align);
mg_iobuf_add(&b, b.len, buf, len, align);
}
intag = 0;
len = 0;
} else if (ch == '<') {
intag = 1;
if (len > 0) mg_iobuf_append(&b, buf, len, align);
if (len > 0) mg_iobuf_add(&b, b.len, buf, len, align);
len = 0;
buf[len++] = (char) (ch & 0xff);
} else if (intag) {
@ -62,13 +62,13 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
} else {
buf[len++] = (char) (ch & 0xff);
if (len >= sizeof(buf)) {
mg_iobuf_append(&b, buf, len, align);
mg_iobuf_add(&b, b.len, buf, len, align);
len = 0;
}
}
}
if (len > 0) mg_iobuf_append(&b, buf, len, align);
if (b.len > 0) mg_iobuf_append(&b, "", 1, align); // nul-terminate
if (len > 0) mg_iobuf_add(&b, b.len, buf, len, align);
if (b.len > 0) mg_iobuf_add(&b, b.len, "", 1, align); // nul-terminate
fclose(fp);
}
(void) depth;

View File

@ -269,11 +269,11 @@ size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
size_t header_len = mkhdr(len, op, c->is_client, header);
// NOTE: order of operations is important!
mg_iobuf_append(&c->send, NULL, header_len, MG_IO_SIZE); // Add header space
p = &c->send.buf[c->send.len - len]; // p points to data
memmove(p, p - header_len, len); // Shift data
memcpy(p - header_len, header, header_len); // Prepend header
mg_ws_mask(c, len); // Mask data
mg_iobuf_add(&c->send, c->send.len, NULL, header_len, MG_IO_SIZE);
p = &c->send.buf[c->send.len - len]; // p points to data
memmove(p, p - header_len, len); // Shift data
memcpy(p - header_len, header, header_len); // Prepend header
mg_ws_mask(c, len); // Mask data
return c->send.len;
}

View File

@ -208,12 +208,22 @@ static void test_iobuf(void) {
ASSERT(io.buf == NULL && io.size == 0 && io.len == 0);
mg_iobuf_resize(&io, 1);
ASSERT(io.buf != NULL && io.size == 1 && io.len == 0);
mg_iobuf_append(&io, "hi", 2, 10);
ASSERT(io.buf != NULL && io.size == 10 && io.len == 2);
ASSERT(memcmp(io.buf, "hi", 2) == 0);
mg_iobuf_append(&io, "!", 1, 10);
ASSERT(io.buf != NULL && io.size == 10 && io.len == 3);
ASSERT(memcmp(io.buf, "hi!", 3) == 0);
ASSERT(memcmp(io.buf, "\x00", 1) == 0);
mg_iobuf_add(&io, 3, "hi", 2, 10);
ASSERT(io.buf != NULL && io.size == 10 && io.len == 5);
ASSERT(memcmp(io.buf, "\x00\x00\x00hi", 5) == 0);
mg_iobuf_add(&io, io.len, "!", 1, 10);
ASSERT(io.buf != NULL && io.size == 10 && io.len == 6);
ASSERT(memcmp(io.buf, "\x00\x00\x00hi!", 6) == 0);
mg_iobuf_add(&io, 0, "x", 1, 10);
ASSERT(memcmp(io.buf, "x\x00\x00\x00hi!", 7) == 0);
ASSERT(io.buf != NULL && io.size == 10 && io.len == 7);
mg_iobuf_del(&io, 1, 3);
ASSERT(io.buf != NULL && io.size == 10 && io.len == 4);
ASSERT(memcmp(io.buf, "xhi!", 3) == 0);
mg_iobuf_del(&io, 10, 100);
ASSERT(io.buf != NULL && io.size == 10 && io.len == 4);
ASSERT(memcmp(io.buf, "xhi!", 3) == 0);
free(io.buf);
}