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 18static 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 50static const char * const tok[] = { 51 "dummy___" 52}; 53 54static signed char 55cb(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 137int 138main(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; 166bail: 167 lecp_destruct(&ctx); 168 169 return ret; 170} 171