mirror of
https://github.com/cesanta/mongoose.git
synced 2024-11-24 02:59:01 +08:00
mg_*rprintf -> mg_*xprintf
This commit is contained in:
parent
189aa80743
commit
d2a27d3d91
@ -2657,7 +2657,7 @@ mg_snprintf(buf, sizeof(buf), "r: %M, %d", f,1,2,7); // r: 3, 7
|
||||
size_t f(void (*out)(char, void *), void *ptr, va_list *ap) {
|
||||
int a = va_arg(*ap, int);
|
||||
int b = va_arg(*ap, int);
|
||||
return mg_rprintf(out, ptr, "%d", a + b);
|
||||
return mg_xprintf(out, ptr, "%d", a + b);
|
||||
}
|
||||
```
|
||||
|
||||
@ -2685,8 +2685,8 @@ free(msg);
|
||||
### mg\_rprintf(), mg\_vrprintf()
|
||||
|
||||
```c
|
||||
size_t mg_rprintf(void (*out)(char, void *), void *param, const char *fmt, ...);
|
||||
size_t mg_vrprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
size_t mg_xprintf(void (*out)(char, void *), void *param, const char *fmt, ...);
|
||||
size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
va_list *ap);
|
||||
```
|
||||
|
||||
@ -2704,7 +2704,7 @@ Usage example:
|
||||
```c
|
||||
void myfn(char c, void *p);
|
||||
|
||||
size_t len = mg_rprintf(myfn, myfn_p, "Double quoted string: %Q!", "hi");
|
||||
size_t len = mg_xprintf(myfn, myfn_p, "Double quoted string: %Q!", "hi");
|
||||
```
|
||||
|
||||
### mg\_pfn\_iobuf()
|
||||
@ -2722,7 +2722,7 @@ Parameters:
|
||||
Usage example:
|
||||
|
||||
```c
|
||||
mg_rprintf(mg_pfn_iobuf, &c->send, "hi!"); // Append to the output buffer
|
||||
mg_xprintf(mg_pfn_iobuf, &c->send, "hi!"); // Append to the output buffer
|
||||
```
|
||||
|
||||
### mg\_to64()
|
||||
|
@ -34,7 +34,7 @@ static size_t printdata(mg_pfn_t out, void *ptr, va_list *ap) {
|
||||
size_t n = 0;
|
||||
if (max > DATA_SIZE) max = DATA_SIZE;
|
||||
while (start < max) {
|
||||
n += mg_rprintf(out, ptr, "%s%d", comma, s_data[start]);
|
||||
n += mg_xprintf(out, ptr, "%s%d", comma, s_data[start]);
|
||||
comma = ",";
|
||||
start++;
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
../webui-plain/main.c
|
63
examples/webui-preact/main.c
Normal file
63
examples/webui-preact/main.c
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2022 Cesanta Software Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// UI example
|
||||
// It implements the following endpoints:
|
||||
// /api/config/get - respond with current config
|
||||
// /api/config/set - POST a config change
|
||||
// any other URI serves static files from s_root_dir
|
||||
// Data and results are JSON strings
|
||||
|
||||
#include "mongoose.h"
|
||||
|
||||
static const char *s_http_addr = "http://localhost:8000"; // HTTP port
|
||||
static const char *s_root_dir = "web_root";
|
||||
#define MQTT_SERVER "mqtt://broker.hivemq.com:1883"
|
||||
#define MQTT_PUBLISH_TOPIC "mg/my_device"
|
||||
#define MQTT_SUBSCRIBE_TOPIC "mg/#"
|
||||
|
||||
static struct config { char *url, *pub, *sub; } s_config;
|
||||
|
||||
// Try to update a single configuration value
|
||||
static void update_config(struct mg_str json, const char *path, char **value) {
|
||||
char *jval;
|
||||
if ((jval = mg_json_get_str(json, path)) != NULL) {
|
||||
free(*value);
|
||||
*value = strdup(jval);
|
||||
}
|
||||
}
|
||||
|
||||
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
|
||||
if (ev == MG_EV_OPEN && c->is_listening) {
|
||||
s_config.url = strdup(MQTT_SERVER);
|
||||
s_config.pub = strdup(MQTT_PUBLISH_TOPIC);
|
||||
s_config.sub = strdup(MQTT_SUBSCRIBE_TOPIC);
|
||||
} else if (ev == MG_EV_HTTP_MSG) {
|
||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||
if (mg_http_match_uri(hm, "/api/config/get")) {
|
||||
mg_http_reply(c, 200, "Content-Type: application/json\r\n",
|
||||
"{%Q:%Q,%Q:%Q,%Q:%Q}\n", "url", s_config.url, "pub",
|
||||
s_config.pub, "sub", s_config.sub);
|
||||
} else if (mg_http_match_uri(hm, "/api/config/set")) {
|
||||
struct mg_str json = hm->body;
|
||||
update_config(json, "$.url", &s_config.url);
|
||||
update_config(json, "$.pub", &s_config.pub);
|
||||
update_config(json, "$.sub", &s_config.sub);
|
||||
mg_http_reply(c, 200, "", "ok\n");
|
||||
} else {
|
||||
struct mg_http_serve_opts opts = {.root_dir = s_root_dir};
|
||||
mg_http_serve_dir(c, ev_data, &opts);
|
||||
}
|
||||
}
|
||||
(void) fn_data;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
struct mg_mgr mgr; // Event manager
|
||||
mg_log_set(MG_LL_INFO); // Set to 3 to enable debug
|
||||
mg_mgr_init(&mgr); // Initialise event manager
|
||||
mg_http_listen(&mgr, s_http_addr, fn, NULL); // Create HTTP listener
|
||||
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||
mg_mgr_free(&mgr);
|
||||
return 0;
|
||||
}
|
@ -30,7 +30,7 @@ static size_t printdata(void (*out)(char, void *), void *ptr, va_list *ap) {
|
||||
const char *comma = "";
|
||||
size_t n = 0;
|
||||
for (int i = 0; i < DATA_SIZE; ++i) {
|
||||
n += mg_rprintf(out, ptr, "%s%d", comma, s_data[i]);
|
||||
n += mg_xprintf(out, ptr, "%s%d", comma, s_data[i]);
|
||||
comma = ",";
|
||||
}
|
||||
return n;
|
||||
|
97
mongoose.c
97
mongoose.c
@ -412,6 +412,32 @@ void mg_error(struct mg_connection *c, const char *fmt, ...) {
|
||||
|
||||
|
||||
|
||||
static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
|
||||
struct mg_iobuf *io = (struct mg_iobuf *) param;
|
||||
if (expand && io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
|
||||
if (io->len + 2 <= io->size) {
|
||||
io->buf[io->len++] = (uint8_t) ch;
|
||||
io->buf[io->len] = 0;
|
||||
} else if (io->len < io->size) {
|
||||
io->buf[io->len++] = 0; // Guarantee to 0-terminate
|
||||
}
|
||||
}
|
||||
|
||||
static void mg_putchar_iobuf_static(char ch, void *param) {
|
||||
mg_pfn_iobuf_private(ch, param, false);
|
||||
}
|
||||
|
||||
void mg_pfn_iobuf(char ch, void *param) {
|
||||
mg_pfn_iobuf_private(ch, param, true);
|
||||
}
|
||||
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
|
||||
struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
|
||||
size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
|
||||
if (n < len) buf[n] = '\0';
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
size_t n;
|
||||
@ -423,7 +449,7 @@ size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
|
||||
|
||||
char *mg_vmprintf(const char *fmt, va_list *ap) {
|
||||
struct mg_iobuf io = {0, 0, 0, 256};
|
||||
mg_vrprintf(mg_pfn_iobuf, &io, fmt, ap);
|
||||
mg_vxprintf(mg_pfn_iobuf, &io, fmt, ap);
|
||||
return (char *) io.buf;
|
||||
}
|
||||
|
||||
@ -436,40 +462,15 @@ char *mg_mprintf(const char *fmt, ...) {
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t mg_rprintf(void (*out)(char, void *), void *ptr, const char *fmt, ...) {
|
||||
size_t mg_xprintf(void (*out)(char, void *), void *ptr, const char *fmt, ...) {
|
||||
size_t len = 0;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
len = mg_vrprintf(out, ptr, fmt, &ap);
|
||||
len = mg_vxprintf(out, ptr, fmt, &ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
|
||||
static void mg_putchar_iobuf_static(char ch, void *param) {
|
||||
struct mg_iobuf *io = (struct mg_iobuf *) param;
|
||||
if (io->len + 2 <= io->size) {
|
||||
io->buf[io->len++] = (uint8_t) ch;
|
||||
io->buf[io->len] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void mg_pfn_iobuf(char ch, void *param) {
|
||||
struct mg_iobuf *io = (struct mg_iobuf *) param;
|
||||
if (io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
|
||||
if (io->len + 2 <= io->size) {
|
||||
io->buf[io->len++] = (uint8_t) ch;
|
||||
io->buf[io->len] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
|
||||
struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
|
||||
size_t n = mg_vrprintf(mg_putchar_iobuf_static, &io, fmt, ap);
|
||||
if (n < len) buf[n] = '\0';
|
||||
// if (len > 0) buf[len - 1] = '\0'; // Guarantee to 0-terminate
|
||||
return n;
|
||||
}
|
||||
|
||||
static bool is_digit(int c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
@ -690,7 +691,7 @@ static size_t bcpy(void (*out)(char, void *), void *ptr, uint8_t *buf,
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t mg_vrprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
va_list *ap) {
|
||||
size_t i = 0, n = 0;
|
||||
while (fmt[i] != '\0') {
|
||||
@ -1647,7 +1648,7 @@ static void mg_http_vprintf_chunk(struct mg_connection *c, const char *fmt,
|
||||
va_list tmp;
|
||||
mg_send(c, " \r\n", 10);
|
||||
va_copy(tmp, ap);
|
||||
mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
|
||||
va_end(tmp);
|
||||
if (c->send.len >= len + 10) {
|
||||
mg_snprintf((char *) c->send.buf + len, 9, "%08lx", c->send.len - len - 10);
|
||||
@ -1702,7 +1703,7 @@ void mg_http_reply(struct mg_connection *c, int code, const char *headers,
|
||||
mg_http_status_code_str(code), headers == NULL ? "" : headers);
|
||||
len = c->send.len;
|
||||
va_start(ap, fmt);
|
||||
mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
|
||||
va_end(ap);
|
||||
if (c->send.len > 15) {
|
||||
mg_snprintf((char *) &c->send.buf[len - 14], 11, "%010lu",
|
||||
@ -2741,7 +2742,7 @@ bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
|
||||
void mg_log(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
mg_vrprintf(s_log_func, s_log_func_param, fmt, &ap);
|
||||
mg_vxprintf(s_log_func, s_log_func_param, fmt, &ap);
|
||||
va_end(ap);
|
||||
logc((unsigned char) '\n');
|
||||
}
|
||||
@ -3282,7 +3283,7 @@ size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) {
|
||||
size_t old = c->send.len;
|
||||
va_list tmp;
|
||||
va_copy(tmp, ap);
|
||||
mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
|
||||
return c->send.len - old;
|
||||
}
|
||||
|
||||
@ -3587,10 +3588,10 @@ void mg_rpc_process(struct mg_rpc_req *r) {
|
||||
void mg_rpc_vok(struct mg_rpc_req *r, const char *fmt, va_list *ap) {
|
||||
int len, off = mg_json_get(r->frame, "$.id", &len);
|
||||
if (off > 0) {
|
||||
mg_rprintf(r->pfn, r->pfn_data, "{%Q:%.*s,%Q:", "id", len,
|
||||
mg_xprintf(r->pfn, r->pfn_data, "{%Q:%.*s,%Q:", "id", len,
|
||||
&r->frame.ptr[off], "result");
|
||||
mg_vrprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
|
||||
mg_rprintf(r->pfn, r->pfn_data, "}");
|
||||
mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
|
||||
mg_xprintf(r->pfn, r->pfn_data, "}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3603,14 +3604,14 @@ void mg_rpc_ok(struct mg_rpc_req *r, const char *fmt, ...) {
|
||||
|
||||
void mg_rpc_verr(struct mg_rpc_req *r, int code, const char *fmt, va_list *ap) {
|
||||
int len, off = mg_json_get(r->frame, "$.id", &len);
|
||||
mg_rprintf(r->pfn, r->pfn_data, "{");
|
||||
mg_xprintf(r->pfn, r->pfn_data, "{");
|
||||
if (off > 0) {
|
||||
mg_rprintf(r->pfn, r->pfn_data, "%Q:%.*s,", "id", len, &r->frame.ptr[off]);
|
||||
mg_xprintf(r->pfn, r->pfn_data, "%Q:%.*s,", "id", len, &r->frame.ptr[off]);
|
||||
}
|
||||
mg_rprintf(r->pfn, r->pfn_data, "%Q:{%Q:%d,%Q:", "error", "code", code,
|
||||
mg_xprintf(r->pfn, r->pfn_data, "%Q:{%Q:%d,%Q:", "error", "code", code,
|
||||
"message");
|
||||
mg_vrprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
|
||||
mg_rprintf(r->pfn, r->pfn_data, "}}");
|
||||
mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
|
||||
mg_xprintf(r->pfn, r->pfn_data, "}}");
|
||||
}
|
||||
|
||||
void mg_rpc_err(struct mg_rpc_req *r, int code, const char *fmt, ...) {
|
||||
@ -3624,7 +3625,7 @@ static size_t print_methods(mg_pfn_t pfn, void *pfn_data, va_list *ap) {
|
||||
struct mg_rpc *h, **head = (struct mg_rpc **) va_arg(*ap, void **);
|
||||
size_t len = 0;
|
||||
for (h = *head; h != NULL; h = h->next) {
|
||||
len += mg_rprintf(pfn, pfn_data, "%s%.*Q", h == *head ? "" : ",",
|
||||
len += mg_xprintf(pfn, pfn_data, "%s%.*Q", h == *head ? "" : ",",
|
||||
(int) h->method.len, h->method.ptr);
|
||||
}
|
||||
return len;
|
||||
@ -5654,7 +5655,7 @@ struct ws_msg {
|
||||
size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
|
||||
va_list *ap) {
|
||||
size_t len = c->send.len;
|
||||
size_t n = mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
size_t n = mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
mg_ws_wrap(c, c->send.len - len, op);
|
||||
return n;
|
||||
}
|
||||
@ -5680,13 +5681,13 @@ static void ws_handshake(struct mg_connection *c, const struct mg_str *wskey,
|
||||
mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
|
||||
mg_sha1_final(sha, &sha_ctx);
|
||||
mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
|
||||
mg_rprintf(mg_pfn_iobuf, &c->send,
|
||||
mg_xprintf(mg_pfn_iobuf, &c->send,
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: %s\r\n",
|
||||
b64_sha);
|
||||
if (fmt != NULL) mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
if (fmt != NULL) mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
if (wsproto != NULL) {
|
||||
mg_printf(c, "Sec-WebSocket-Protocol: %.*s\r\n", (int) wsproto->len,
|
||||
wsproto->ptr);
|
||||
@ -5873,7 +5874,7 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
|
||||
struct mg_str host = mg_url_host(url);
|
||||
mg_random(nonce, sizeof(nonce));
|
||||
mg_base64_encode((unsigned char *) nonce, sizeof(nonce), key);
|
||||
mg_rprintf(mg_pfn_iobuf, &c->send,
|
||||
mg_xprintf(mg_pfn_iobuf, &c->send,
|
||||
"GET %s HTTP/1.1\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Host: %.*s\r\n"
|
||||
@ -5884,10 +5885,10 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
|
||||
if (fmt != NULL) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
|
||||
va_end(ap);
|
||||
}
|
||||
mg_rprintf(mg_pfn_iobuf, &c->send, "\r\n");
|
||||
mg_xprintf(mg_pfn_iobuf, &c->send, "\r\n");
|
||||
c->pfn = mg_ws_cb;
|
||||
c->pfn_data = NULL;
|
||||
}
|
||||
|
@ -791,8 +791,8 @@ size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex);
|
||||
double mg_atod(const char *buf, int len, int *numlen);
|
||||
size_t mg_dtoa(char *buf, size_t len, double d, int width);
|
||||
|
||||
size_t mg_vrprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
|
||||
size_t mg_rprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
|
||||
size_t mg_vxprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
|
||||
size_t mg_xprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
|
||||
size_t mg_snprintf(char *, size_t, const char *fmt, ...);
|
||||
char *mg_vmprintf(const char *fmt, va_list *ap);
|
||||
|
59
src/fmt.c
59
src/fmt.c
@ -1,6 +1,32 @@
|
||||
#include "fmt.h"
|
||||
#include "iobuf.h"
|
||||
|
||||
static void mg_pfn_iobuf_private(char ch, void *param, bool expand) {
|
||||
struct mg_iobuf *io = (struct mg_iobuf *) param;
|
||||
if (expand && io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
|
||||
if (io->len + 2 <= io->size) {
|
||||
io->buf[io->len++] = (uint8_t) ch;
|
||||
io->buf[io->len] = 0;
|
||||
} else if (io->len < io->size) {
|
||||
io->buf[io->len++] = 0; // Guarantee to 0-terminate
|
||||
}
|
||||
}
|
||||
|
||||
static void mg_putchar_iobuf_static(char ch, void *param) {
|
||||
mg_pfn_iobuf_private(ch, param, false);
|
||||
}
|
||||
|
||||
void mg_pfn_iobuf(char ch, void *param) {
|
||||
mg_pfn_iobuf_private(ch, param, true);
|
||||
}
|
||||
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
|
||||
struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
|
||||
size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
|
||||
if (n < len) buf[n] = '\0';
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
size_t n;
|
||||
@ -12,7 +38,7 @@ size_t mg_snprintf(char *buf, size_t len, const char *fmt, ...) {
|
||||
|
||||
char *mg_vmprintf(const char *fmt, va_list *ap) {
|
||||
struct mg_iobuf io = {0, 0, 0, 256};
|
||||
mg_vrprintf(mg_pfn_iobuf, &io, fmt, ap);
|
||||
mg_vxprintf(mg_pfn_iobuf, &io, fmt, ap);
|
||||
return (char *) io.buf;
|
||||
}
|
||||
|
||||
@ -25,40 +51,15 @@ char *mg_mprintf(const char *fmt, ...) {
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t mg_rprintf(void (*out)(char, void *), void *ptr, const char *fmt, ...) {
|
||||
size_t mg_xprintf(void (*out)(char, void *), void *ptr, const char *fmt, ...) {
|
||||
size_t len = 0;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
len = mg_vrprintf(out, ptr, fmt, &ap);
|
||||
len = mg_vxprintf(out, ptr, fmt, &ap);
|
||||
va_end(ap);
|
||||
return len;
|
||||
}
|
||||
|
||||
static void mg_putchar_iobuf_static(char ch, void *param) {
|
||||
struct mg_iobuf *io = (struct mg_iobuf *) param;
|
||||
if (io->len + 2 <= io->size) {
|
||||
io->buf[io->len++] = (uint8_t) ch;
|
||||
io->buf[io->len] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void mg_pfn_iobuf(char ch, void *param) {
|
||||
struct mg_iobuf *io = (struct mg_iobuf *) param;
|
||||
if (io->len + 2 > io->size) mg_iobuf_resize(io, io->len + 2);
|
||||
if (io->len + 2 <= io->size) {
|
||||
io->buf[io->len++] = (uint8_t) ch;
|
||||
io->buf[io->len] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
|
||||
struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
|
||||
size_t n = mg_vrprintf(mg_putchar_iobuf_static, &io, fmt, ap);
|
||||
if (n < len) buf[n] = '\0';
|
||||
// if (len > 0) buf[len - 1] = '\0'; // Guarantee to 0-terminate
|
||||
return n;
|
||||
}
|
||||
|
||||
static bool is_digit(int c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
@ -279,7 +280,7 @@ static size_t bcpy(void (*out)(char, void *), void *ptr, uint8_t *buf,
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t mg_vrprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
size_t mg_vxprintf(void (*out)(char, void *), void *param, const char *fmt,
|
||||
va_list *ap) {
|
||||
size_t i = 0, n = 0;
|
||||
while (fmt[i] != '\0') {
|
||||
|
@ -11,8 +11,8 @@ size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex);
|
||||
double mg_atod(const char *buf, int len, int *numlen);
|
||||
size_t mg_dtoa(char *buf, size_t len, double d, int width);
|
||||
|
||||
size_t mg_vrprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
|
||||
size_t mg_rprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
|
||||
size_t mg_vxprintf(void (*)(char, void *), void *, const char *fmt, va_list *);
|
||||
size_t mg_xprintf(void (*fn)(char, void *), void *, const char *fmt, ...);
|
||||
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap);
|
||||
size_t mg_snprintf(char *, size_t, const char *fmt, ...);
|
||||
char *mg_vmprintf(const char *fmt, va_list *ap);
|
||||
|
@ -272,7 +272,7 @@ static void mg_http_vprintf_chunk(struct mg_connection *c, const char *fmt,
|
||||
va_list tmp;
|
||||
mg_send(c, " \r\n", 10);
|
||||
va_copy(tmp, ap);
|
||||
mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
|
||||
va_end(tmp);
|
||||
if (c->send.len >= len + 10) {
|
||||
mg_snprintf((char *) c->send.buf + len, 9, "%08lx", c->send.len - len - 10);
|
||||
@ -327,7 +327,7 @@ void mg_http_reply(struct mg_connection *c, int code, const char *headers,
|
||||
mg_http_status_code_str(code), headers == NULL ? "" : headers);
|
||||
len = c->send.len;
|
||||
va_start(ap, fmt);
|
||||
mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
|
||||
va_end(ap);
|
||||
if (c->send.len > 15) {
|
||||
mg_snprintf((char *) &c->send.buf[len - 14], 11, "%010lu",
|
||||
|
@ -51,7 +51,7 @@ bool mg_log_prefix(int level, const char *file, int line, const char *fname) {
|
||||
void mg_log(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
mg_vrprintf(s_log_func, s_log_func_param, fmt, &ap);
|
||||
mg_vxprintf(s_log_func, s_log_func_param, fmt, &ap);
|
||||
va_end(ap);
|
||||
logc((unsigned char) '\n');
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ size_t mg_vprintf(struct mg_connection *c, const char *fmt, va_list ap) {
|
||||
size_t old = c->send.len;
|
||||
va_list tmp;
|
||||
va_copy(tmp, ap);
|
||||
mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &tmp);
|
||||
return c->send.len - old;
|
||||
}
|
||||
|
||||
|
18
src/rpc.c
18
src/rpc.c
@ -40,10 +40,10 @@ void mg_rpc_process(struct mg_rpc_req *r) {
|
||||
void mg_rpc_vok(struct mg_rpc_req *r, const char *fmt, va_list *ap) {
|
||||
int len, off = mg_json_get(r->frame, "$.id", &len);
|
||||
if (off > 0) {
|
||||
mg_rprintf(r->pfn, r->pfn_data, "{%Q:%.*s,%Q:", "id", len,
|
||||
mg_xprintf(r->pfn, r->pfn_data, "{%Q:%.*s,%Q:", "id", len,
|
||||
&r->frame.ptr[off], "result");
|
||||
mg_vrprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
|
||||
mg_rprintf(r->pfn, r->pfn_data, "}");
|
||||
mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
|
||||
mg_xprintf(r->pfn, r->pfn_data, "}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,14 +56,14 @@ void mg_rpc_ok(struct mg_rpc_req *r, const char *fmt, ...) {
|
||||
|
||||
void mg_rpc_verr(struct mg_rpc_req *r, int code, const char *fmt, va_list *ap) {
|
||||
int len, off = mg_json_get(r->frame, "$.id", &len);
|
||||
mg_rprintf(r->pfn, r->pfn_data, "{");
|
||||
mg_xprintf(r->pfn, r->pfn_data, "{");
|
||||
if (off > 0) {
|
||||
mg_rprintf(r->pfn, r->pfn_data, "%Q:%.*s,", "id", len, &r->frame.ptr[off]);
|
||||
mg_xprintf(r->pfn, r->pfn_data, "%Q:%.*s,", "id", len, &r->frame.ptr[off]);
|
||||
}
|
||||
mg_rprintf(r->pfn, r->pfn_data, "%Q:{%Q:%d,%Q:", "error", "code", code,
|
||||
mg_xprintf(r->pfn, r->pfn_data, "%Q:{%Q:%d,%Q:", "error", "code", code,
|
||||
"message");
|
||||
mg_vrprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
|
||||
mg_rprintf(r->pfn, r->pfn_data, "}}");
|
||||
mg_vxprintf(r->pfn, r->pfn_data, fmt == NULL ? "null" : fmt, ap);
|
||||
mg_xprintf(r->pfn, r->pfn_data, "}}");
|
||||
}
|
||||
|
||||
void mg_rpc_err(struct mg_rpc_req *r, int code, const char *fmt, ...) {
|
||||
@ -77,7 +77,7 @@ static size_t print_methods(mg_pfn_t pfn, void *pfn_data, va_list *ap) {
|
||||
struct mg_rpc *h, **head = (struct mg_rpc **) va_arg(*ap, void **);
|
||||
size_t len = 0;
|
||||
for (h = *head; h != NULL; h = h->next) {
|
||||
len += mg_rprintf(pfn, pfn_data, "%s%.*Q", h == *head ? "" : ",",
|
||||
len += mg_xprintf(pfn, pfn_data, "%s%.*Q", h == *head ? "" : ",",
|
||||
(int) h->method.len, h->method.ptr);
|
||||
}
|
||||
return len;
|
||||
|
12
src/ws.c
12
src/ws.c
@ -17,7 +17,7 @@ struct ws_msg {
|
||||
size_t mg_ws_vprintf(struct mg_connection *c, int op, const char *fmt,
|
||||
va_list *ap) {
|
||||
size_t len = c->send.len;
|
||||
size_t n = mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
size_t n = mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
mg_ws_wrap(c, c->send.len - len, op);
|
||||
return n;
|
||||
}
|
||||
@ -43,13 +43,13 @@ static void ws_handshake(struct mg_connection *c, const struct mg_str *wskey,
|
||||
mg_sha1_update(&sha_ctx, (unsigned char *) magic, 36);
|
||||
mg_sha1_final(sha, &sha_ctx);
|
||||
mg_base64_encode(sha, sizeof(sha), (char *) b64_sha);
|
||||
mg_rprintf(mg_pfn_iobuf, &c->send,
|
||||
mg_xprintf(mg_pfn_iobuf, &c->send,
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: %s\r\n",
|
||||
b64_sha);
|
||||
if (fmt != NULL) mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
if (fmt != NULL) mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, ap);
|
||||
if (wsproto != NULL) {
|
||||
mg_printf(c, "Sec-WebSocket-Protocol: %.*s\r\n", (int) wsproto->len,
|
||||
wsproto->ptr);
|
||||
@ -236,7 +236,7 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
|
||||
struct mg_str host = mg_url_host(url);
|
||||
mg_random(nonce, sizeof(nonce));
|
||||
mg_base64_encode((unsigned char *) nonce, sizeof(nonce), key);
|
||||
mg_rprintf(mg_pfn_iobuf, &c->send,
|
||||
mg_xprintf(mg_pfn_iobuf, &c->send,
|
||||
"GET %s HTTP/1.1\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Host: %.*s\r\n"
|
||||
@ -247,10 +247,10 @@ struct mg_connection *mg_ws_connect(struct mg_mgr *mgr, const char *url,
|
||||
if (fmt != NULL) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
mg_vrprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
|
||||
mg_vxprintf(mg_pfn_iobuf, &c->send, fmt, &ap);
|
||||
va_end(ap);
|
||||
}
|
||||
mg_rprintf(mg_pfn_iobuf, &c->send, "\r\n");
|
||||
mg_xprintf(mg_pfn_iobuf, &c->send, "\r\n");
|
||||
c->pfn = mg_ws_cb;
|
||||
c->pfn_data = NULL;
|
||||
}
|
||||
|
@ -1414,13 +1414,13 @@ static bool sccmp(const char *s1, const char *s2, int expected) {
|
||||
static size_t pf1(void (*out)(char, void *), void *ptr, va_list *ap) {
|
||||
int a = va_arg(*ap, int);
|
||||
int b = va_arg(*ap, int);
|
||||
return mg_rprintf(out, ptr, "%d", a + b);
|
||||
return mg_xprintf(out, ptr, "%d", a + b);
|
||||
}
|
||||
|
||||
static size_t pf2(void (*out)(char, void *), void *ptr, va_list *ap) {
|
||||
int cnt = va_arg(*ap, int);
|
||||
size_t n = 0;
|
||||
while (cnt-- > 0) n += mg_rprintf(out, ptr, "%d", cnt);
|
||||
while (cnt-- > 0) n += mg_xprintf(out, ptr, "%d", cnt);
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -1510,6 +1510,14 @@ static void test_str(void) {
|
||||
mg_snprintf(buf, sizeof(buf), "%Q", "");
|
||||
ASSERT(strcmp(buf, expected) == 0);
|
||||
|
||||
expected = "";
|
||||
mg_snprintf(buf, 1, "%s", "abc");
|
||||
ASSERT(strcmp(buf, expected) == 0);
|
||||
|
||||
expected = "a";
|
||||
mg_snprintf(buf, 2, "%s", "abc");
|
||||
ASSERT(strcmp(buf, expected) == 0);
|
||||
|
||||
expected = "\"hi, \\\"\"";
|
||||
mg_snprintf(buf, sizeof(buf), "\"hi, %q\"", "\"");
|
||||
MG_INFO(("[%s] [%s]", buf, expected));
|
||||
@ -1535,9 +1543,9 @@ static void test_str(void) {
|
||||
ASSERT(strcmp(p, "[9876543210,7]") == 0);
|
||||
free(p);
|
||||
|
||||
mg_rprintf(mg_pfn_iobuf, &io, "[%M", pf2, 10);
|
||||
mg_rprintf(mg_pfn_iobuf, &io, ",");
|
||||
mg_rprintf(mg_pfn_iobuf, &io, "%d]", 7);
|
||||
mg_xprintf(mg_pfn_iobuf, &io, "[%M", pf2, 10);
|
||||
mg_xprintf(mg_pfn_iobuf, &io, ",");
|
||||
mg_xprintf(mg_pfn_iobuf, &io, "%d]", 7);
|
||||
ASSERT(strcmp((char *) io.buf, "[9876543210,7]") == 0);
|
||||
mg_iobuf_free(&io);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user