1 /*
2 * lejp test app
3 *
4 * Written in 2010-2019 by Andy Green <andy@warmcat.com>
5 *
6 * This file is made available under the Creative Commons CC0 1.0
7 * Universal Public Domain Dedication.
8 *
9 * This demonstrates a minimal http server that performs a form GET with a couple
10 * of parameters. It dumps the parameters to the console log and redirects
11 * to another page.
12 */
13
14 #include <libwebsockets.h>
15 #include <string.h>
16
17
18 static const char * const reason_names[] = {
19 "LECPCB_CONSTRUCTED",
20 "LECPCB_DESTRUCTED",
21 "LECPCB_START",
22 "LECPCB_COMPLETE",
23 "LECPCB_FAILED",
24 "LECPCB_PAIR_NAME",
25 "LECPCB_VAL_TRUE",
26 "LECPCB_VAL_FALSE",
27 "LECPCB_VAL_NULL",
28 "LECPCB_VAL_NUM_INT",
29 "LECPCB_VAL_RESERVED", /* float in lejp */
30 "LECPCB_VAL_STR_START",
31 "LECPCB_VAL_STR_CHUNK",
32 "LECPCB_VAL_STR_END",
33 "LECPCB_ARRAY_START",
34 "LECPCB_ARRAY_END",
35 "LECPCB_OBJECT_START",
36 "LECPCB_OBJECT_END",
37 "LECPCB_TAG_START",
38 "LECPCB_TAG_END",
39 "LECPCB_VAL_NUM_UINT",
40 "LECPCB_VAL_UNDEFINED",
41 "LECPCB_VAL_FLOAT16",
42 "LECPCB_VAL_FLOAT32",
43 "LECPCB_VAL_FLOAT64",
44 "LECPCB_VAL_SIMPLE",
45 "LECPCB_VAL_BLOB_START",
46 "LECPCB_VAL_BLOB_CHUNK",
47 "LECPCB_VAL_BLOB_END",
48 };
49
50 static const char * const tok[] = {
51 "dummy___"
52 };
53
54 static signed char
cb(struct lecp_ctx * ctx,char reason)55 cb(struct lecp_ctx *ctx, char reason)
56 {
57 char buf[1024], *p = buf, *end = &buf[sizeof(buf)];
58 int n;
59
60 for (n = 0; n < ctx->sp; n++)
61 *p++ = ' ';
62 *p = '\0';
63
64 lwsl_notice("%s%s: path %s match %d statckp %d\r\n", buf,
65 reason_names[(unsigned int)(reason) &
66 (LEJP_FLAG_CB_IS_VALUE - 1)], ctx->path,
67 ctx->path_match, ctx->pst[ctx->pst_sp].ppos);
68
69 if (reason & LECP_FLAG_CB_IS_VALUE) {
70
71 switch (reason) {
72 case LECPCB_VAL_NUM_UINT:
73 p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
74 " value %llu ",
75 (unsigned long long)ctx->item.u.u64);
76 break;
77 case LECPCB_VAL_STR_START:
78 case LECPCB_VAL_STR_CHUNK:
79 case LECPCB_VAL_STR_END:
80 p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
81 " value '%s' ", ctx->buf);
82 break;
83
84 case LECPCB_VAL_BLOB_START:
85 case LECPCB_VAL_BLOB_CHUNK:
86 case LECPCB_VAL_BLOB_END:
87 if (ctx->npos)
88 lwsl_hexdump_notice(ctx->buf, (size_t)ctx->npos);
89 break;
90
91 case LECPCB_VAL_NUM_INT:
92 p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
93 " value %lld ",
94 (long long)ctx->item.u.i64);
95 break;
96 case LECPCB_VAL_FLOAT16:
97 case LECPCB_VAL_FLOAT32:
98 case LECPCB_VAL_FLOAT64:
99 break;
100
101 case LECPCB_VAL_SIMPLE:
102 p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
103 " simple %llu ",
104 (unsigned long long)ctx->item.u.u64);
105 break;
106 }
107 if (ctx->ipos) {
108 int n;
109
110 p += lws_snprintf(p, lws_ptr_diff_size_t(end, p), "(array indexes: ");
111 for (n = 0; n < ctx->ipos; n++)
112 p += lws_snprintf(p, lws_ptr_diff_size_t(end, p), "%d ", ctx->i[n]);
113 p += lws_snprintf(p, lws_ptr_diff_size_t(end, p), ") ");
114 }
115
116 lwsl_notice("%s \r\n", buf);
117
118 (void)reason_names; /* NO_LOGS... */
119 return 0;
120 }
121
122 switch (reason) {
123 case LECPCB_COMPLETE:
124 lwsl_notice("%sParsing Completed (LEJPCB_COMPLETE)\n", buf);
125 break;
126 case LECPCB_PAIR_NAME:
127 lwsl_notice("%spath: '%s' (LEJPCB_PAIR_NAME)\n", buf, ctx->path);
128 break;
129 case LECPCB_TAG_START:
130 lwsl_notice("LECPCB_TAG_START: %llu\r\n", (unsigned long long)ctx->item.u.u64);
131 return 0;
132 }
133
134 return 0;
135 }
136
137 int
main(int argc,char * argv[])138 main(int argc, char *argv[])
139 {
140 int fd, n = 1, ret = 1, m = 0;
141 struct lecp_ctx ctx;
142 char buf[128];
143
144 lws_set_log_level(7, NULL);
145
146 lwsl_notice("libwebsockets-test-lecp (C) 2017 - 2021 andy@warmcat.com\n");
147 lwsl_notice(" usage: cat my.cbor | libwebsockets-test-lecp\n\n");
148
149 lecp_construct(&ctx, cb, NULL, tok, LWS_ARRAY_SIZE(tok));
150
151 fd = 0;
152
153 while (n > 0) {
154 n = (int)read(fd, buf, sizeof(buf));
155 if (n <= 0)
156 continue;
157
158 m = lecp_parse(&ctx, (uint8_t *)buf, (size_t)n);
159 if (m < 0 && m != LEJP_CONTINUE) {
160 lwsl_err("parse failed %d\n", m);
161 goto bail;
162 }
163 }
164 lwsl_notice("okay (%d)\n", m);
165 ret = 0;
166 bail:
167 lecp_destruct(&ctx);
168
169 return ret;
170 }
171