mg_*rprintf -> mg_*xprintf

This commit is contained in:
cpq 2022-08-13 20:34:20 +01:00
parent 189aa80743
commit d2a27d3d91
14 changed files with 185 additions and 113 deletions

View File

@ -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()

View File

@ -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++;
}

View File

@ -1 +0,0 @@
../webui-plain/main.c

View 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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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') {

View File

@ -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);

View File

@ -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",

View File

@ -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');
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}