cesanta / frozen Goto Github PK
View Code? Open in Web Editor NEWJSON parser and generator for C/C++ with scanf/printf like interface. Targeting embedded systems.
License: Other
JSON parser and generator for C/C++ with scanf/printf like interface. Targeting embedded systems.
License: Other
I cant find json_parse2
, or find_json_token
anywhere.
I have tried looking for different branches, but the only thing i found is
this documentation referencing it.
This used to be part of the mongoose API, but disappeared somewhere in the past 6 months if I'm correct.
What do? halp
Why do I get no output from this code?
`
char buf[200] = "";
const char *str = "{\"OrderUuid\":\"8dbf1ded-0ff5-421d-bc79-f3299375620\"}";
json_scanf(str, strlen(str), "{OrderUuid: %s}", buf);
printf("%s\n", buf);
`
If I remove the last 4 numbers from "8dbf1ded-0ff5-421d-bc79-f3299375620" it works as expected.
You recently switched to Apache commons 2.0 license for frozen.
Can you create a 1.6-APL release under Apache commons 2.0 license as a fork from Tag 1.6? Or is there any GPL code in 1.6 so you are forced to have a GPL license?
it's not clear how to get at nested objects, ie {foo:{bar:"data"}}
is it possible?
Hi,
I tried the first example 'Example - scan arbitrary JSON string:' from README.md and found that:
current:
// str has the following JSON string (notice keys are out of order):
// { "a": 123, "d": true, "b": [1, 2], "c": "hi" }
int a, b;
char *c;
void *my_data = NULL;
json_scanf(str, strlen(str), "{ a:%d, b:%M, c:%Q, d:%B }",
&a, scan_array, my_data, &c, &b);
better:
// str has the following JSON string (notice keys are out of order):
// { "a": 123, "d": true, "b": [1, 2], "c": "hi" }
int a = 0, d = 0;
char *c = NULL;
void *my_data = NULL;
json_scanf(str, strlen(str), "{ a:%d, b:%M, c:%Q, d:%B }",
&a, scan_array, my_data, &c, &d);
regards
Stefan
$ cppcheck --force .
Checking frozen.c ...
frozen.c:866:49: error: Pointer addition with NULL pointer. [nullPointerArithmetic]
char *send = (char *) src + slen, *dend = dst + dlen, *orig_dst = dst, *p;
^
frozen.c:949:67: note: Calling function 'json_unescape', 3rd argument 'NULL' value is 0
int unescaped_len = json_unescape(token->ptr, token->len, NULL, 0);
^
frozen.c:866:49: note: Null pointer addition
char *send = (char *) src + slen, *dend = dst + dlen, *orig_dst = dst, *p;
^
frozen.c:561:3: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
va_copy(ap, xap);
^
frozen.c:572:30: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
int64_t val = va_arg(ap, int64_t);
^
frozen.c:578:29: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
size_t val = va_arg(ap, size_t);
^
frozen.c:583:43: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
json_printf_callback_t f = va_arg(ap, json_printf_callback_t);
^
frozen.c:584:24: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
len += f(out, &ap);
^
frozen.c:586:26: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
int val = va_arg(ap, int);
^
frozen.c:592:27: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
int i, n = va_arg(ap, int);
^
frozen.c:593:41: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
const unsigned char *p = va_arg(ap, const unsigned char *);
^
frozen.c:603:41: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
const unsigned char *p = va_arg(ap, const unsigned char *);
^
frozen.c:604:24: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
int n = va_arg(ap, int);
^
frozen.c:615:31: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
l = (size_t) va_arg(ap, int);
^
frozen.c:618:20: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
p = va_arg(ap, char *);
^
frozen.c:652:9: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
va_copy(ap_copy, ap);
^
frozen.c:676:13: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
va_copy(ap_copy, ap);
^
frozen.c:696:25: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
(void) va_arg(ap, int64_t);
^
frozen.c:698:25: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
(void) va_arg(ap, int);
^
frozen.c:699:25: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
(void) va_arg(ap, char *);
^
frozen.c:704:29: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
(void) va_arg(ap, int);
^
frozen.c:741:3: error: va_list 'ap' used before va_start() was called. [va_list_usedBeforeStarted]
va_end(ap);
^
frozen.c:652:9: error: va_list 'ap_copy' used before va_start() was called. [va_list_usedBeforeStarted]
va_copy(ap_copy, ap);
^
frozen.c:653:48: error: va_list 'ap_copy' used before va_start() was called. [va_list_usedBeforeStarted]
need_len = vsnprintf(pbuf, size, fmt2, ap_copy);
^
frozen.c:654:9: error: va_list 'ap_copy' used before va_start() was called. [va_list_usedBeforeStarted]
va_end(ap_copy);
^
frozen.c:676:13: error: va_list 'ap_copy' used before va_start() was called. [va_list_usedBeforeStarted]
va_copy(ap_copy, ap);
^
frozen.c:677:49: error: va_list 'ap_copy' used before va_start() was called. [va_list_usedBeforeStarted]
vsnprintf(pbuf, need_len + 1, fmt2, ap_copy);
^
frozen.c:678:13: error: va_list 'ap_copy' used before va_start() was called. [va_list_usedBeforeStarted]
va_end(ap_copy);
^
Checking frozen.c: JSON_ENABLE_BASE64...
Checking frozen.c: JSON_ENABLE_HEX...
Checking frozen.c: JSON_MINIMAL=0...
Checking frozen.c: WEAK...
Checking frozen.c: WEAK;_WIN32;__GNUC__;__TI_COMPILER_VERSION__...
Checking frozen.c: _WIN32...
Checking frozen.c: _WIN32;__GNUC__...
1/2 files checked 56% done
Checking unit_test.c ...
frozen.c:812:28: error: Pointer addition with NULL pointer. [nullPointerArithmetic]
frozen.end = json_string + json_string_length;
^
unit_test.c:122:3: note: Calling function 'json_walk', 1st argument 'NULL' value is 0
ASSERT(json_walk(NULL, 0, NULL, 0) == JSON_STRING_INVALID);
^
frozen.c:812:28: note: Null pointer addition
frozen.end = json_string + json_string_length;
^
Checking unit_test.c: JSON_ENABLE_BASE64...
Checking unit_test.c: JSON_ENABLE_HEX...
Checking unit_test.c: JSON_MINIMAL=0...
Checking unit_test.c: WEAK...
Checking unit_test.c: WEAK;_WIN32;__GNUC__;__TI_COMPILER_VERSION__...
Checking unit_test.c: _MSC_VER...
Checking unit_test.c: _WIN32...
Checking unit_test.c: _WIN32;__GNUC__...
2/2 files checked 100% done
Hi there
This really look great.
Is it possibly to get this working on an ESP8266/NodeMCU (arduino IDE)
I'm happy to test and feedback with results.
I need to serialize an array of struct to a file and back again
Den
These would be nice to have. Assuming that they're universally supported, of course, which I haven't confirmed.
I'm not sure if the library should fail if JSON input string contains '\0'
symbols, because the API requires the length of input data specified. Why not skip that symbol as a whitespace?
Add these to incomplete_tests in unit_test.c: "{a:t", "{a:f", "{a:n",
and you get a test failure- the parser returns JSON_STRING_INVALID
when it should return JSON_STRING_INCOMPLETE
.
This is because the tests in parse_value
for true
, false
, and null
attempt to match the entire value only. They need to match a partial value as well, and if it is partial, return JSON_STRING_INCOMPLETE
.
May I suggest something like this (for each of null
, true
, and false
):
} else if (ch == 'n') {
TRY(test_and_skip(f, 'n'));
TRY(test_and_skip(f, 'u'));
TRY(test_and_skip(f, 'l'));
TRY(test_and_skip(f, 'l'));
TRY(capture_ptr(f, f->cur - 4, JSON_TYPE_NULL));
capture_len(f, f->num_tokens - 1, f->cur);
Which seems to work, but is a little bit ugly.
data
is allocated twice here
Hello,
i've found that unlike original scanf(), the json_scanf() does not support "scanset" feature. Eg.:
json_scanf(in, sizeof(in), "{ str:%30[0-9a-zA-Z ] }", out);
should scan string of up to 30 characers from set [0-9a-zA-Z ] = both cases of alphanumeric characters and space. But it does not work in frozen.
Have you considered implementing this useful feature of scanf() to json_scanf()?
Also it would be nice to have some way to get pointer and length of escaped JSON string. sometimes there's no need to unescape so i would love to have way to parse string without using dynamic memory allocation, so it's faster and i don't have to free() anything...
Something like this would be great:
json_scanf(in, sizeof(in), "{ str:%.*s }", out.len, out.ptr);
i've used %.*s
because that's how printf() handles situation where you want to pass string length along with pointer... But maybe %S
would be nice option as well. in such case json_scanf() should return whole length of string minus the quotes (but still json escaped).
The unit_test.c in the master branch still has the GPL license header:
https://github.com/cesanta/frozen/blob/master/unit_test.c
`...This library is dual-licensed: you can redistribute it and/or modify
It should be replaced with a reference to the Apache Commons Licence.
Not a huge thing, but JSON_OUT_BUF
and JSON_OUT_FILE
don't compile under C++. Something like this might work:
#define MY_JSON_OUT_FILE(fp) { \
.printer = mg_json_printer_mbuf, \
.u = { \
.fp = fp \
} \
}
Hi, hope you would be doing great.
Consider following code from main.c from you code files, I've just replaced the static string json with mine. Issue is if string is starting with [ (square brace), function execution ends at parse_json line. I wanted to asked does you code supports json starting with square brackets, i.e., arrays. Also, does its support underscore (_) in keys, e.g., when i replace 'id' with '_id' it give me same behavior as described above.
static const char *test_nested(void) {
struct json_token ar[100];
const char *s = "[{"id":123,"bookmark":1,"date":430654481,"title":"Welcome to IE7","url":"http://go.microsoft.com/fwlink/?linkid=68919","visits":1}]";
enum json_type types[] = {JSON_TYPE_OBJECT, JSON_TYPE_STRING, JSON_TYPE_ARRAY, JSON_TYPE_OBJECT, JSON_TYPE_STRING, JSON_TYPE_NUMBER, JSON_TYPE_STRING, JSON_TYPE_NUMBER, JSON_TYPE_STRING, JSON_TYPE_NUMBER, JSON_TYPE_STRING, JSON_TYPE_STRING, JSON_TYPE_STRING, JSON_TYPE_STRING, JSON_TYPE_STRING, JSON_TYPE_NUMBER, JSON_TYPE_EOF
};
int i, ar_size = ARRAY_SIZE(ar), types_size = ARRAY_SIZE(types);
ASSERT(parse_json(s, strlen(s), ar, ar_size) == (int) strlen(s));
for (i = 0; i < types_size; i++) {
ASSERT(ar[i].type == types[i]);
}
ASSERT(find_json_token(ar, "a[0]") == &ar[3]);
ASSERT(find_json_token(ar, "a[0][0]") == &ar[4]);
ASSERT(find_json_token(ar, "a[0][1]") == &ar[5]);
ASSERT(find_json_token(ar, "a[0][2]") == &ar[6]);
ASSERT(find_json_token(ar, "a[0][2].b") == &ar[8]);
return NULL;
}
Any help will be appreciated. Thanks in advance.
Cheers. :)
I'm trying to parse a json string looks like this
{
"a": { "a": 1 },
"b": { "b": 2 }
}
The code I used follows
char buff[] = "{\"a\":{\"a\":1},\"b\":{\"b\":2}}";
int len = sizeof(buff);
int a = 0, b = 0;
json_scanf(buff, len, "{a:{a:%d},b:{b:%d}}", &a, &b);
printf("a %d b %d\n", a, b);
outputs
a 1 b 0
Only a
got parsed. Any idea on how to also parse b
?
Hello,
cessanta hosts two JSON libraries:
https://github.com/cesanta/mjson/ (~1.0 kLoC)
https://github.com/cesanta/frozen/ (~1.5 kLoC)
Both seem to be tiny. Is there any reccomendation on which library to use for specific use cases?
I think it might be useful to cross-reference and mention this in READMEs of both libraries, so users can make better decisions when choosing between the two.
Thanks.
char *payload = "{\"a\":1}";
struct json_out out = JSON_OUT_BUF(output, output_len);
json_setf(input, input_len, &out, ".sign", "%Q", "5738263BEFF11EC874D99623AC22A3B1");
output:
{"a":1,"sign":"5738263BEFF11EC874D99623AC22A3B1"}
Works grate
char *payload = "{\"service\":\"service.parking.detail\",\"a\":1}";
struct json_out out = JSON_OUT_BUF(output, output_len);
json_setf(input, input_len, &out, ".sign", "%Q", "5738263BEFF11EC874D99623AC22A3B1");
outpu:
{"service":"service.parking.detail","a":1,"59DEE02F6A5CBA08F66FA862BF88EF76"}
Not Working!
Hello, I'm considering using this nice library on our limited 8-bit AVR MCU.
I probably will have to tweak it:
Do you have any suggestions, existing attempts, research?
Are you accepting pull requests (respecting backwards compatibility)?
Thanks
Joris
Hello
I'm working on queuing MQTT messages in the absence of internet and I ran into a problem writing a file to disk, my input is
{"three":2,"two":2,"one":2}
when I use function json_vfprintf
the data stored on the disk looks like this
{""three"":1,""two"":1,""one"":1}
which is incompatible with JSON
Is it possible to call the function so that it doesn't add another " to the JSON or in somehow delete extra " from file ?
I receive a json object, wich has several informations and also an array of interfaces wuth several informations for each of them.
The array can be of any size (from one element to 4, 5 or even 6 elements).
The json is this:
{"status": "1", "message": "No Errors", "channel": "TEST", "writes": "481725079297", "cpu": "1.22", "memory": "403440", "ports": {"enp7s0f1": [{"byteIn": "118585715528669","byteOut": "1094749498510","packetIn": "78618393261","packetOut": "8078419574"}],"enp6s0f1": [{"byteIn": "0","byteOut": "0","packetIn": "0","packetOut": "0"}],"enp3s0": [{"byteIn": "0","byteOut": "0","packetIn": "0","packetOut": "0"}],"enp7s0f0": [{"byteIn": "0","byteOut": "0","packetIn": "0","packetOut": "0"}],"enp6s0f0": [{"byteIn": "0","byteOut": "0","packetIn": "0","packetOut": "0"}],"lo": [{"byteIn": "1532650647","byteOut": "1532650647","packetIn": "5444282","packetOut": "544428"}]}}
I need to parse the ports array.
So, I did this way:
json_scanf(buf, strlen(buf), "{ status: %Q, message: %Q, channel: %Q , writes: %Q, cpu: %Q, memory: %Q }", &status, &message, &channel, &writes, &cpu, &mem);
printf("status: %s\nmessage: %s\nchannel: %s\nwrites: %s\ncpu: %s\nmem: %s\n", status, message, channel, writes, cpu, mem);
static void scan_array2(const char *str, int len, void *user_data) {
struct json_token t;
int i;
float bytein;
printf("Parsing array: %.*s\n", len, str);
for (i = 0; json_scanf_array_elem(str, len, "", i, &t) > 0; i++) {
printf("Index %d, token %.*s\n", i, t.len, t.ptr);
json_scanf(t.ptr, t.len, "{byteIn: %f}", &bytein);
printf("Bytes in: %f\n", bytein);
}
}
The result is:
status: 1
message: No Errors
channel: TEST
writes: 481725079297
cpu: 1.22
mem: 403440
Parsing array: {"enp7s0f1": [{"byteIn": "118585715528669","byteOut": "1094749498510","packetIn": "78618393261","packetOut": "8078419574"}],"enp6s0f1": [{"byteIn": "0","byteOut": "0","packetIn": "0","packetOut": "0"}],"enp3s0": [{"byteIn": "0","byteOut": "0","packetIn": "0","packetOut": "0"}],"enp7s0f0": [{"byteIn": "0","byteOut": "0","packetIn": "0","packetOut": "0"}],"enp6s0f0": [{"byteIn": "0","byteOut": "0","packetIn": "0","packetOut": "0"}],"lo": [{"byteIn": "1532650647","byteOut": "1532650647","packetIn": "5444282","packetOut": "544428"}]}
It doesn't parse the array, even entering the method scan_array2.
Can you help to find how thi scan be done? The examples are not clear, for me.
Thnaks
Hi,
My json looks something like this: "b : [1,2]", I couldn't extract it using json_scanf and callback.
reproduce code (taken from the README.md):
static void scan_array(const char *str, int len, void *user_data) {
struct json_token t;
int i;
printf("Parsing array: %.*s\n", len, str);
for (i = 0; json_scanf_array_elem(str, len, ".x", i, &t) > 0; i++) {
printf("We are in the loop");
}
}int a, b;
char *c;
void *my_data = NULL;
char *str = "{ a: 123, d: true, b: [1, 2], c: hi }";
json_scanf(str, strlen(str), "{ a:%d, b:%M, c:%Q, d:%B }", &a, scan_array, my_data, &c, &b);
It never get's in the loop...
I assume the path shouldn't be ".x" but didn't find any documentation on what it should be (and empty string didn't work)
Thanks!
This is a great library. I would like to suggest adding sorting JSON functionality. It can by sort by number, date, alphabet in ascending or descending order.
int my_struct_print(struct json_out *out, va_list *ap)
{
struct my_struct *p = va_arg(*ap, struct my_struct *);
return json_printf(out, "{a_int: %d, b12345int: %d}", p->a, p->b);
}
json_printf(&out, "%M\n", my_struct_print, &mys);
produce the {"a""int": 1, "b""int": 2}
Why? Must be {"a_int": 1, "b12345nt": 2}
or not?
If a JSON object contains null property values, json_scanf with a %Q formatter converts these properties to a string containing the word "null" instead of a NULL string.
For example, in the sample unit test below, I expect that result should be NULL, but instead it contains the string "null".
{
const char *str = "{a : null }";
char *result = NULL;
ASSERT(json_scanf(str, strlen(str), "{a: %Q}", &result) == 0);
ASSERT(result == NULL);
free(result);
}
json_sprinter reallocates destination buffer by one character every time it's called.
It'd be nice to reduce the number of reallocations
char json[50] = "{}";
char json_out[50];
struct json_out out = JSON_OUT_BUF(json_out, sizeof(json_out));
json_setf(json, sizeof(json), &out, ".somekey", "true");
only writes the value into json_out and thus creates an invalid json
printf("%s\n", json_out); // outut: "true"
Hi,
Thanks for your work on this parser, this is the first time i work with JSON and frozen has been very helpful.
I'm able to parse ints and booleans from the JSON object str
but i haven't been able to parse the string value from the key b
. Here's the code i'm using:
#include <string.h>
#include <stdlib.h>
#include "frozen.h"
int main(void)
{
const char *header = "JSON: ";
const char *val_a = "Valor del key a: ";
const char *val_b = "Valor del key b: ";
const char *val_c = "Valor del key c: ";
// JSON Object
const char *str= "{ \"a\": 123, \"b\": \"hi\", \"c\": true }";
// Holders for the values
int value_c = 0;
int value_a = 0;
char value_b[20];
memset(value_b, '\0', sizeof(value_b));
char msg_val[30];
memset(msg_val, '\0', sizeof(msg_val));
json_scanf(str, strlen(str), "{c:%B, a:%d}", &value_c, &value_a);
int result = json_scanf(str, strlen(str), "{b: %Q}", value_b);
HAL_UART_Transmit(&huart2, header, strlen(header), 500);
HAL_UART_Transmit(&huart2, str, strlen(str), 500);
HAL_UART_Transmit(&huart2, "\r\n", 2, 500);
HAL_UART_Transmit(&huart2, val_a, strlen(val_a), 500);
sprintf(msg_val, "%d\r\n", value_a);
HAL_UART_Transmit(&huart2, msg_val, strlen(msg_val), 500);
memset(msg_val, '\0', sizeof(msg_val));
HAL_UART_Transmit(&huart2, val_b, strlen(val_b), 500);
sprintf(msg_val, "result: %d, %s\r\n", result, value_b);
HAL_UART_Transmit(&huart2, msg_val, strlen(msg_val), 500);
HAL_UART_Transmit(&huart2, val_c, strlen(val_c), 500);
sprintf(msg_val, "%s\r\n", value_c ? "true" : "false");
HAL_UART_Transmit(&huart2, msg_val, strlen(msg_val), 500);
memset(msg_val, '\0', sizeof(msg_val));
free(value_b);
while (1) {
}
}
And this is the output i'm getting from the code above:
JSON: { "a": 123, "b": "hi", "c": true }
Valor del key a: 123
Valor del key b: result: 1, P
Valor del key c: true
I searched on here and the mongoose-os forum but haven't been able to solve my problem.
Regards,
Carlos
Hi,
While i was auditing frozen library using PyJFuzz, I came across a crash due to invalid call (call rax) , this is highly exploitable since allow full control over EIP just parsing the JSON, below the tastcase!
a735561449d2493fcaddab8c5b8147ad0622636a.txt
I didn't investigate further the root cause, anyway seems to be related to callback function.
Regards,
Daniele Linguaglossa
Do you have any plans on releasing an up to date version of frozen? I'd like to include frozen into nixpkgs with a current version including cross-compilation support. I therefore opened PR #71 in order to ease cross-compilation over there.
frozen.c под виндой (VC++2010) не компилируется без вот такого
p.s.
А можно перевести int type на enum?
ужасно не удобно под отладчиком с этими #define - видны только магические числа
struct json_token {
const char *ptr; // Points to the beginning of the token
int len; // Token length
int num_desc; // For arrays and object, total number of descendants
int type; // Type of the token, possible values below
};
Hi,
While I was auditing frozen library using PyJFuzz, I came across a stack based overflow using the following testcase with address sanitizer.
e1f555ceb332dc1717778aba679cfdda20939edf.txt
I didn't investigate further, anyway there're other exploitable issue, I'll report later.
Thanks for your support!
Regards,
Daniele
Example code:
void test_case(float arr[], size_t len)
{
for (int i = 0; i < len; i++) {
printf("%f\n", arr[i]);
}
char *json = json_asprintf("{state:{reported:{temps:%M}}}",
json_printf_array, arr, len * sizeof(arr[0]),
sizeof(arr[0]), "%f");
if (json) {
printf("%s\n", json);
free(json);
}
}
int main(int argc, char *argv[])
{
float arr[3] = {
1.1,
2.2,
3.3
};
test_case(arr, 3);
return 0;
}
The printf of the loop is correct. The correct number of elements are added to the json, but they are all zero. This is being compiled for the esp32 with xtensa-esp32-elf-gcc (crosstool-NG crosstool-ng-1.22.0-80-g6c4433a) 5.2.0
I've copied the elements to an array of double using "%lf" and this is a workaround for the problem.
Edit: Added a main and tested on amd64 as well, and repro'd there too. I was worried this might be due to the esp32 hardware float lazy context switch.
Hello, I think I found some bugs in frozen.
Attached file is a zip file which includes 3 source codes to reproduce them.
Each source code should be compiled with below option.
clang -fsanitize=address -m32 -g -O0 -o bugX bugX.c frozen.c
Thanks.
Hello,
frozen license had been changed to Apache License 2.
Do you have plan to do a release under Apache License 2 in short term?
Thank you very much.
Hello,
below the code I'm running
strcpy( s_in, "{"Hello":1,"b":2}" );
printf( "Initial : %s\n", s_in ); // {"Hello":1,"b":2} => OK
struct json_out out = JSON_OUT_BUF( s_out, sizeof( s_out ) );
json_setf( s_in, sizeof( s_in ), &out, ".Hello", "7" );
strcpy( s_in, s_out );
printf( "Step 1 : %s\n", s_in ); // {"Hello":7,"b":2} => OK
out.u.buf.len = 0;
json_setf( s_in, sizeof( s_in ), &out, ".b", "8" );
strcpy( s_in, s_out );
printf( "Step 2 : %s\n", s_in ); // {"Hello":7,"b":8} => OK
out.u.buf.len = 0;
json_setf( s_in, sizeof( s_in ), &out, ".Goodbye", "10" ); // {"Hello":7,"b":8,"G":10} => G instead of Goodbye
strcpy( s_in, s_out );
printf( "Step 3 : %s\n", s_in );
On the latest block, trying to add Goodby key, and got G.
Hello,
i am trying to iterate over array of structs. There are 3 elements and i can iterate over it in for() { printf() }
loops, but i can't get json_printf_array()
to call custom struct handler for each element. Any ideas what is wrong with my code? Causes segfault.
int print_my_struct(struct json_out *out, va_list *ap) {
struct mgos_lib_info *p = va_arg(*ap, struct mgos_lib_info *);
return json_printf(out, "{name: %s, version: %s}", p->name, p->version);
}
int main(void) {
printf("------------------\n");
for(size_t i = 0; i < (sizeof(mgos_libs_info) / sizeof(struct mgos_lib_info))-1; i++) {
printf("FHS DETECTED MODULE: %s version %s (init:%d)\n",
mgos_libs_info[i].name,
mgos_libs_info[i].version,
mgos_libs_info[i].init
);
}
printf("------------------\n");
for (const struct mgos_lib_info *l = mgos_libs_info; l->name != NULL; l++) {
printf("FHS DETECTED MODULE: %s version %s\n", l->name, l->version);
}
printf("------------------\n");
char *json = json_asprintf("{modules:%M}",
json_printf_array, mgos_libs_info, 3 * sizeof(mgos_libs_info[0]),
sizeof(mgos_libs_info[0]), "%M", print_my_struct);
if (json) {
printf("%s\n", json);
free(json);
}
}
int ret = 0;
char ret_str[256];
char* str = "{\"ret\":0,\"base64_info\":"oookkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"}";
memset(ret_str,0,sizeof(ret_str));
int a = json_scanf(str, strlen(str), "{ret:%d,base64_info:%s}",&ret, ret_str); // parse error: a == 1
It works ok if "base64_info" is a short string。
Parsing and dumping a JSON object that contains a key which ends with a dot results in the respective entry missing from the output. I've build a minimal working sample to reproduce the behavior:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "frozen.h"
#define BUFFER_SIZE 8192
int run(const char* Data, size_t Size)
{
char* json_buf = (char*)malloc(BUFFER_SIZE);
if (NULL == json_buf) {
return -1;
}
struct json_out out = JSON_OUT_BUF(json_buf, BUFFER_SIZE);
if (0 > json_prettify(Data, Size, &out)) {
free(json_buf);
return -1;
}
printf("%s\n", json_buf);
free(json_buf);
return 0;
}
int main(int argc, char** argv) {
run(argv[1], strlen(argv[1]));
}
clang -I ./frozen main.c frozen/frozen.c -o main
./main "{\"key\": 10, \"hidden.\": 20}"
Expected:
{
"key": 10,
"hidden.": 20
}
Actual:
{
"key": 10
}
From your online docs:
int a, b;
char *c;
json_scanf(str, strlen(str), "{ a:%d, b:%M, c:%Q, d:%B }",
&a, &b, &c, scan_array, my_data);
It would seem that the actual call should be
int a, b;
char *c;
json_scanf(str, strlen(str), "{ a:%d, b:%M, c:%Q, d:%B }",
&a, scan_array, my_data, &c, &b );
a: %d matches the integer a
b: %M matches the scanner function & user data
c: %Q matches the address of the char* for the string data
d: %B matches bool which gets copied to int b
Am I missing something?
Hi,
I want to manipulate json data for example
"{ "a": 123, "b": [ 1 ], "c": true }" // this is taken from your unit_test.c file
Want to change "a" value to 7
json_setf(szJSON, strlen(szJSON), &out, ".a", "%d", 7);
I am getting following output
{ "a": 7, "b": [ 1 ], "c": t
Last 5 characters get truncated.
Could you please look into this issue.
Note: above string works if we remove SPACE after COMMA and SPACE inside the ARRAY
Here is my code:
void main()
{
char *szJSON = "{ "a": 123, "b": [ 1 ], "c": true }";
char buf[1024];
struct json_out out = JSON_OUT_BUF(buf, sizeof(buf));
memset(buf, 0, 1024);
json_setf(szJSON, strlen(szJSON), &out, ".a", "%d", 7);
printf("%s\n\n", buf);
getch();
}
modifying line 1066:
i.e.
} else if (json_isalpha(fmt[i]) || json_get_utf8_char_len(fmt[i]) > 1 ) {
to
} else if ( json_isdigit(fmt[i]) || json_isalpha(fmt[i]) || json_get_utf8_char_len(fmt[i]) > 1 ) {
works fine.
Hi there! thanks for frozen!
this line
Line 47 in d763609
__int64
to correctly compile for win 64bit according to my tests, conducted using mingw32 in cross-compilation to target w64.I have been using this library in a project of mine (it's great, btw). My project is supporting the Arduino platform. It took some alteration to make the library work correctly on arduino, due to Arduino seemingly lacking support for %.*s syntax in snprintf. I was able to work around this by using temporary buffers in place of the %.*s syntax.
I'm not sure if this change is desirable for the master version of the library. If Arduino support is desired, I will happily make a pull request.
Input -
json = {"a":0,"b":{"e":"hello"},"c":{"d":"Test"}}
Operation 1-
json_scanf(json, strlen(json),"{c:%T}", &data)
Output - {"d":"Test"} - Correct
Operation 2 -
json_scanf(json, strlen(json),"{b:%T}", &data)
Output - {"e":"hello"},"c":{"d":"Test"}}- Inorrect, it appends the remaining json string as well.
Hello,
can you please add support for json5 style comments?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.