2020-12-05 19:26:32 +08:00
|
|
|
#include "iobuf.h"
|
2022-07-02 00:28:06 +08:00
|
|
|
#include "arch.h"
|
2020-12-05 19:26:32 +08:00
|
|
|
#include "log.h"
|
|
|
|
|
2021-04-29 15:49:23 +08:00
|
|
|
// Not using memset for zeroing memory, cause it can be dropped by compiler
|
|
|
|
// See https://github.com/cesanta/mongoose/pull/1265
|
|
|
|
static void zeromem(volatile unsigned char *buf, size_t len) {
|
|
|
|
if (buf != NULL) {
|
|
|
|
while (len--) *buf++ = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-01 19:53:25 +08:00
|
|
|
static size_t roundup(size_t size, size_t align) {
|
|
|
|
return align == 0 ? size : (size + align - 1) / align * align;
|
|
|
|
}
|
|
|
|
|
2021-01-29 20:32:34 +08:00
|
|
|
int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) {
|
|
|
|
int ok = 1;
|
2022-08-01 19:53:25 +08:00
|
|
|
new_size = roundup(new_size, io->align);
|
2020-12-05 19:26:32 +08:00
|
|
|
if (new_size == 0) {
|
2021-04-29 15:49:23 +08:00
|
|
|
zeromem(io->buf, io->size);
|
2020-12-05 19:26:32 +08:00
|
|
|
free(io->buf);
|
|
|
|
io->buf = NULL;
|
|
|
|
io->len = io->size = 0;
|
|
|
|
} else if (new_size != io->size) {
|
2021-05-18 00:36:57 +08:00
|
|
|
// NOTE(lsm): do not use realloc here. Use calloc/free only, to ease the
|
2020-12-05 19:26:32 +08:00
|
|
|
// porting to some obscure platforms like FreeRTOS
|
2021-05-18 00:36:57 +08:00
|
|
|
void *p = calloc(1, new_size);
|
2020-12-05 19:26:32 +08:00
|
|
|
if (p != NULL) {
|
2021-03-22 19:30:29 +08:00
|
|
|
size_t len = new_size < io->len ? new_size : io->len;
|
2022-03-01 00:51:46 +08:00
|
|
|
if (len > 0) memmove(p, io->buf, len);
|
2021-04-29 15:49:23 +08:00
|
|
|
zeromem(io->buf, io->size);
|
2020-12-05 19:26:32 +08:00
|
|
|
free(io->buf);
|
|
|
|
io->buf = (unsigned char *) p;
|
|
|
|
io->size = new_size;
|
|
|
|
} else {
|
2021-01-29 20:32:34 +08:00
|
|
|
ok = 0;
|
2022-02-13 02:17:25 +08:00
|
|
|
MG_ERROR(("%lld->%lld", (uint64_t) io->size, (uint64_t) new_size));
|
2020-12-05 19:26:32 +08:00
|
|
|
}
|
|
|
|
}
|
2021-01-29 20:32:34 +08:00
|
|
|
return ok;
|
2020-12-05 19:26:32 +08:00
|
|
|
}
|
|
|
|
|
2022-08-01 19:53:25 +08:00
|
|
|
int mg_iobuf_init(struct mg_iobuf *io, size_t size, size_t align) {
|
2022-04-12 16:53:42 +08:00
|
|
|
io->buf = NULL;
|
2022-08-01 19:53:25 +08:00
|
|
|
io->align = align;
|
2022-04-12 16:53:42 +08:00
|
|
|
io->size = io->len = 0;
|
2021-02-15 22:42:22 +08:00
|
|
|
return mg_iobuf_resize(io, size);
|
2020-12-05 19:26:32 +08:00
|
|
|
}
|
|
|
|
|
2021-08-28 15:08:54 +08:00
|
|
|
size_t mg_iobuf_add(struct mg_iobuf *io, size_t ofs, const void *buf,
|
2022-08-01 19:53:25 +08:00
|
|
|
size_t len) {
|
|
|
|
size_t new_size = roundup(io->len + len, io->align);
|
|
|
|
mg_iobuf_resize(io, new_size); // Attempt to resize
|
|
|
|
if (new_size != io->size) len = 0; // Resize failure, append nothing
|
2021-08-28 15:08:54 +08:00
|
|
|
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;
|
2020-12-05 19:26:32 +08:00
|
|
|
io->len += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2021-08-27 17:25:24 +08:00
|
|
|
size_t mg_iobuf_del(struct mg_iobuf *io, size_t ofs, size_t len) {
|
|
|
|
if (ofs > io->len) ofs = io->len;
|
|
|
|
if (ofs + len > io->len) len = io->len - ofs;
|
2022-03-14 21:26:00 +08:00
|
|
|
if (io->buf) memmove(io->buf + ofs, io->buf + ofs + len, io->len - ofs - len);
|
|
|
|
if (io->buf) zeromem(io->buf + io->len - len, len);
|
2020-12-05 19:26:32 +08:00
|
|
|
io->len -= len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mg_iobuf_free(struct mg_iobuf *io) {
|
2021-02-15 22:42:22 +08:00
|
|
|
mg_iobuf_resize(io, 0);
|
2020-12-05 19:26:32 +08:00
|
|
|
}
|