ibireme / yyjson Goto Github PK
View Code? Open in Web Editor NEWThe fastest JSON library in C
Home Page: https://ibireme.github.io/yyjson/doc/doxygen/html/
License: MIT License
The fastest JSON library in C
Home Page: https://ibireme.github.io/yyjson/doc/doxygen/html/
License: MIT License
Lines 5712 to 5717 in 19220b1
The code is inconsistent to the comment. Which is the lower_bound_closer
case? Refer to the shorter interval case in the Dragonbox paper, I believe the code is more correct than the comment.
How does 131237
come? It seems not the best magic, although already works for [-1074, 971] with u = 20. (When u = 20, even the best one may fail with e = -1335.)
Description
When enabling the YYJSON_READ_ALLOW_INF_AND_NAN
flag, the JSON read fails, returning an unexpected character
error with code 6
.
char_is_number(*cur)
check, and handled accordingly.Additional context
Running the code below results in these two errors:
Array JSON read error: unexpected character. Code: 6, at position: 28
Object JSON read error: unexpected character. Code: 6, at position: 78
How to reproduce
yyjson_read_flag flg = YYJSON_READ_ALLOW_INF_AND_NAN;
//
// Read array with nan and inf values
//
char arr_str[] = "[1, 123e999, nan, NaN, NAN, inf, infinity, Infinity, INF, -inf, -infinity, -Infinity, -INF]";
size_t arr_str_len = strlen(arr_str);
yyjson_read_err arr_err;
yyjson_doc *arr_doc = yyjson_read_opts(arr_str, arr_str_len, flg, NULL, &arr_err);
if (!arr_doc) {
fprintf(stderr, "Array JSON read error: %s. Code: %u, at position: %ld\n", arr_err.msg, arr_err.code, arr_err.pos);
}
yyjson_doc_free(arr_doc);
//
// Read object with nan and inf values
//
char obj_str[] = "{\"small\": 1, \"large\": 123e999, \"nan1\": nan, \"nan2\": NaN, \"nan3\": NAN, \"inf1\": inf, \"inf2\": infinity, \"inf3\": Infinity, \"inf4\": INF, \"inf5\": -inf, \"inf6\": -infinity, \"inf7\": -Infinity, \"inf8\": -INF}";
size_t obj_str_len = strlen(obj_str);
yyjson_read_err obj_err;
yyjson_doc *obj_doc = yyjson_read_opts(obj_str, obj_str_len, flg, NULL, &obj_err);
if (!obj_doc) {
fprintf(stderr, "Object JSON read error: %s. Code: %u, at position: %ld\n", obj_err.msg, obj_err.code, obj_err.pos);
}
yyjson_doc_free(obj_doc);
Possible fix
Replace all instances of:
if (has_flag(ALLOW_INF_AND_NAN) && *cur == 'N')
with:
if (has_flag(ALLOW_INF_AND_NAN) && *cur == 'i' || *cur == 'I' || *cur == 'N')
Example 1:
{
"deviceId":"11223344",
"eventType":"Alarm",
"value":
[
{
"type":"heart",
"upperLimit":"10:00:00",
"lowerLimit":"15:04:00"
},
{
"type":"heart",
"upperLimit":"17:01:00",
"lowerLimit":"21:15:00"
}
]
}
Example 2:
{
"deviceId":"11223344",
"eventType":"deviceEvent",
"value":
[
{
"type":"online",
"value":"yes"
}
]
}
一般的JSON解析用您的yyjson库非常方便,但是这种复杂点的没有例子,不会用了,希望作者能在百忙中回复一下
Hello, I'm trying to add some strings and integers to the for loop, but it's not working.It contains some empty strings
`
for (auto& c : row) {
auto obj = yyjson_mut_arr_add_obj(write_doc, write_val);
yyjson_mut_obj_add_int(write_doc, obj, "id", c[0].as_int());
yyjson_mut_obj_add_str(write_doc, obj, "username", c[1].as_string().c_str());
yyjson_mut_obj_add_str(write_doc, obj, "nick", c[2].as_string().c_str());
fmt::print("{}\n", c[1].as_string().c_str());
yyjson_mut_obj_add_val(write_doc, obj, "phone", yyjson_mut_strn(write_doc, c[3].as_string().c_str(), c[3].as_string().length()));
yyjson_mut_obj_add_val(write_doc, obj, "weixin", yyjson_mut_strn(write_doc, c[4].as_string().c_str(), c[4].as_string().length()));
yyjson_mut_obj_add_int(write_doc, obj, "createtime", c[5].as_int());
yyjson_mut_obj_add_int(write_doc, obj, "logintime", c[6].as_int());
yyjson_mut_obj_add_val(write_doc, obj, "loginrecord", yyjson_mut_strn(write_doc, c[7].as_string().c_str(), c[7].as_string().length()));
yyjson_mut_obj_add_val(write_doc, obj, "usermessage", yyjson_mut_strn(write_doc, c[8].as_string().c_str(), c[8].as_string().length()));
}
`
The result of fmt::print is correct and it prints the corresponding string
4565464 sadasdsa
However, the output of 'username' Json looks like this. Why
{"code":0,"data":[{"id":1,"username":"\u0000adasds","nick":"","phone":"\u000056","weixin":"","createtime":0,"logintime":0,"loginrecord":"","usermessage":""},{"id":2,"username":"\u0000adasdsa","nick":"","phone":"\u000056","weixin":"","createtime":0,"logintime":0,"loginrecord":"","usermessage":""}]}
His first 'username' should be 4565464 and his second 'username' should be 'sadasdsa' but now they are both \u0000adasds which is strange
I find it common to want to replace the value discovered by a call to yyjson_mut_get_pointer
, however the current API provides no context about where in the document the match was found.
I propose a yyjson_mut_get_pointern_ex
(which yyjson_mut_get_pointer
would use) with something like:
yyjson_mut_val * yyjson_mut_get_pointern_ex(
const char *pointer,
size_t pointer_len,
yyjson_mut_val *container,
const char *key,
size_t *idx;
)
This would return the pointer as it does now, but would also populate container
(if not NULL
) with the yyjson_mut_val
that contains the matching value. If container
is a yyjson_mut_obj
, it would populate key
with the matching key. If container
is a yyjson_mut_arr
, it would populate idx
. This would provide enough information to replace the returned value in its parent.
I'm happy to implement this one, but I'm hoping you have an idea for a better API.
Describe the bug
I have this Json that comes from the Discord API: {\"url\": \"wss://gateway.discord.gg\", \"shards\": 1, \"session_start_limit\": {\"total\": 1000, \"remaining\": 986, \"reset_after\": 1501475, \"max_concurrency\": 1}}\r\n0\r\n\r\n
and i do this to try to read it:
yyjson_doc *json_doc = yyjson_read(json, strlen(json), 0);
yyjson_val *root = yyjson_doc_get_root(json_doc);
yyjson_val *url = yyjson_obj_get(root, "url");
But the json_doc pointer always returns NULL, and I don't know what it could be, because I've already checked Json's formatting on a website and it's all right, I've already checked the string and it's all right, I don't know what could be happening anymore
Your environment
Additional context
I installed the library by vcpkg
Describe the bug
I am working for the project, it needs some fields are wittern to json, but there are garbled characters in the fields that generate json.
Your environment
Additional context
here is the generate json, please look at the PersonAppearTime field, I don't know what's wrong is it?
//=================================================================================
"URI": "/VIID/Person",
"Method": "POST",
"X-Statistics": "TraceId=7f27da55bb6e4031bd9078e96494dab9;Camera=34040000111310100055,20220914171604000;CPSS=000905123456785,20220914171604656,20220914171604855,90;",
"Content": {
"PersonListObject": {
"PersonObject": [
{
"PersonID": "22020422999999999999999999999999999999999999999",
"DeviceID": "34040000111310100055",
"InfoKind": 3,
"SourceID": "22020422001321001366022020091514153701019",
"LeftTopX": 1663,
"LeftTopY": 653,
"RightBtmX": 1733,
"RightBtmY": 753,
"LocationMarkTime": "20220914171604000",
"PersonAppearTime": "\u0005\u0005\u0000\u0000\u0000\u0000\u0000\u0000�h�\u0000\u0000\u0000\u0000\u0000�",
"PersonDisAppearTime": "20220914171604000",
"IDType": "990",
"IDNumber": "19",
//=================================================================================
the code:
yyjson_mut_doc pdoc = yyjson_mut_doc_new(NULL);
vector<string> vtBufs;
yyjson_mut_val *root = yyjson_mut_obj(pdoc);
yyjson_mut_doc_set_root(pdoc,root);
//MessageID
yyjson_mut_obj_add_str(pdoc,root,"MessageID",struuid.c_str());
//SourceDeviceID
yyjson_mut_obj_add_str(pdoc,root,"SourceDeviceID",CpssConfig::GetInstance()->m_sourceDeviceID.c_str());
//Uri
yyjson_mut_obj_add_str(pdoc,root,"URI","/VIID/Faces");
//Method
yyjson_mut_obj_add_str(pdoc,root,"Method","POST");
//........................
//LocationMarkTime
if (m_UsedPerson->LocationMarkTime.bUsed)
{ yyjson_mut_obj_add_str(pdoc,pPersonData,"LocationMarkTime",CFuncLib::TimeToDataTime(m_LocationMarkTime).c_str());
}
//PersonAppearTime
if (m_UsedPerson->PersonAppearTime.bUsed)
{ yyjson_mut_obj_add_str(pdoc,pPersonData,"PersonAppearTime",CFuncLib::TimeToDataTime(m_PersonAppearTime).c_str());
}
//PersonDisAppearTime
if (m_UsedPerson->PersonDisAppearTime.bUsed)
{ yyjson_mut_obj_add_str(pdoc,pPersonData,"PersonDisAppearTime",CFuncLib::TimeToDataTime(m_PersonDisAppearTime).c_str());
}
Describe the bug
When compiled with flag -m32
reading the following JSON returns NULL
. Reading is fine when compiling for 64-bit.
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
}
Your environment
Additional context
DuckDB uses yyjson for its JSON extension. We had no issues with this specific JSON string before (it is part of our tests). I updated yyjson to the latest version, and this issue occurred.
Can you add a method without changing its position?
For example yyjson_mut_obj_replace
Any reason why yyjson_read_opts doesn't accept const char *
?
I have to cast:
yyjson_doc *parse(std::string_view inputString) {
yyjson_read_flag flags = 0;
yyjson_read_err error;
auto jsonDoc = yyjson_read_opts((char *)inputString.data(), inputString.length(), flags, nullptr, &error);
Is your feature request related to a problem? Please describe.
The library requires loading into its own data structure when reading and building a data structure when writing.
This incurs some overhead if one wants to just load or save a custom data structure.
Describe the solution you'd like
It would be good to have a direct interface to the low-level parser, maybe in terms of callbacks for reading. For writing, just exposing a simple API to format the various JSON elements might be good.
Describe alternatives you've considered
Right now, one parses the data into the yyjson
document and then reads from it.
I'd like to be able to merge/patch json documents. Preferably: https://datatracker.ietf.org/doc/html/rfc7386
Hi ibireme
Thank you very much for your last reply, but I found a problem, please help me to solve it, and I look forward to your reply
//How to find yyjson_mut_val* according to key
yyjson_mut_val* getOrCreateChildMutObj(yyjson_mut_doc doc, yyjson_mut_val parent, const std::string &key)
{
yyjson_mut_val* child = yyjson_mut_get_pointer(parent, key.data());
if (!child)// if not find, build key/value
{
child = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, parent, key.data(), child);
}
return child;
}
//How to find array nodes(yyjson_mut_val*) based on key ?
yyjson_mut_val* getOrCreateArray(yyjson_mut_doc *doc, yyjson_mut_val arryParent, const std::string &key)
{
yyjson_mut_val arry = yyjson_mut_get_pointer(arryParent, key.data());
if (!arry)
{
arry = yyjson_mut_arr(doc);
yyjson_mut_obj_add_val(doc, arryParent, key.data(), arry);
}
return arry;
}
void funcLayout(yyjson_mut_doc *doc)
{
std::string key1("PATH_KEY_NODE");
std::string key2("INFO_KEY_NODE");
//case 1
{
// auto val = getOrCreateChildMutObj(doc, doc->root, key1);
// yyjson_mut_val* layoutKeyNode = getOrCreateChildMutObj(doc, doc->root, key2);
//output: It seems something went wrong
/*
{
"???"m�\u0000\u0000?K\u0001\u0000": {},
"INFO_KEY?????�": {}
}
*/
}
//case 2
{
yyjson_mut_val* child = yyjson_mut_get_pointer(doc->root, key1.data());
if (!child)
{
child = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, doc->root, key1.data(), child);
}
yyjson_mut_val* child1 = yyjson_mut_get_pointer(doc->root, key2.data());
if (!child1)
{
child1 = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, doc->root, key2.data(), child1);
}
//output: Should be correct
/*
{
"PATH_KEY_NODE": {},
"INFO_KEY_NODE": {}
}
*/
}
}
void writeJson()
{
yyjson_mut_doc *doc = yyjson_mut_doc_new(nullptr);
yyjson_mut_doc_set_root(doc, yyjson_mut_obj(doc));
funcLayout(doc);
//funcVerify(doc);
yyjson_write_flag flg = YYJSON_WRITE_PRETTY /| YYJSON_WRITE_ESCAPE_UNICODE/;
yyjson_write_err err;
yyjson_mut_write_file("config.json", doc, flg, nullptr, &err);
yyjson_mut_doc_free(doc);
}
////////////////
Use yyjson in qt :
1、The result of this use is wrong :
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
writeJson(); //////////////////////////
return a.exec();
}
2、The result of calling at the very beginning of the program is correct
int main(int argc, char *argv[])
{
writeJson(); //The result of calling at the very beginning of the program is correct
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
//////////////////////////////////
The output result of my case 2 method should be correct, but the output result of case 1 seems to be wrong. Can't you use function calls? There is still a problem with the method I use. Looking forward to your reply, thank you
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::string key1("LAYOUT_PATH_KEY_NODE");
std::string key2("VERIFY_KEY_NODE");
std::string input("input_layout");
std::string output("output_layout");
std::string outlevel("output_level");
//case 1
{
yyjson_mut_val* child1 = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, doc->root, "ROOT", child1);
getOrCreateChildMutObj(doc, child1, "key2");
getOrCreateChildMutObj(doc, child1, "key23");
yyjson_mut_val* layoutKeyNode = getOrCreateChildMutObj(doc, child1, key1);
yyjson_mut_val* arryNode = getOrCreateArray(doc, layoutKeyNode, outlevel);
//Is there a problem with inserting data like this???
std::vector<std::string> v{"kkkkk33333", "wwwwwwwwww", "rrrrrrrrrr", "qqqqqqqqqqqqq"};
for(size_t i = 0; i < v.size(); ++i)
yyjson_mut_arr_add_strcpy(doc, arryNode, v[i].data());
#This way of access is correct, but how do I want to dynamically insert data?
// yyjson_mut_arr_add_strcpy(doc, arryNode, "yyyyyyy");
// yyjson_mut_arr_add_strcpy(doc, arryNode, "out/debug/bin/config.json");
// yyjson_mut_arr_add_strcpy(doc, arryNode, "out/debug/bin/config2.json");
// yyjson_mut_arr_add_strcpy(doc, arryNode, "ttxttttt");
}
output:
"ROOT": {
"key2": {},
"key23": {},
"LAYOUT_PATH_KEY_NODE": {
"�\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000": [
"kkkkk33333",
"wwwwwwwwww",
"rrrrrrrrrr",
"qqqqqqqqqqqqq"
]
}
}
Hi ibireme
how do I want to dynamically insert data?
for example :
std::vectorstd::string v{"kkkkk33333", "wwwwwwwwww", "rrrrrrrrrr", "qqqqqqqqqqqqq"};
yyjson_mut_val* arryNode; //obj or arry
for(size_t i = 0; i < v.size(); ++i)
yyjson_mut_arr_add_strcpy(doc, arryNode, v[i].data());
The file name suffix is .cpp, then compile with g++ ,Can I use g++ to compile?
///////////////////////////////////////////
I want to edit a yyjson_val
object. So I want to convert it to yyjson_mut_val
edit it and then convert it back to yyjson_val
.
What's the ideal way to do this?
Hello, could you add a support of writing Inf and NaN values as null, maybe via a writer flag?
Currently a apply this patch for yyjson in my project to achieve this:
diff --git a/src/yyjson.c b/src/yyjson.c
index 6a571b5..dc973a3 100644
--- a/src/yyjson.c
+++ b/src/yyjson.c
@@ -5635,7 +5635,8 @@ static_noinline u8 *write_f64_raw(u8 *buf, u64 raw, bool allow_nan_and_inf) {
return buf + 3;
}
} else {
- return NULL;
+ *(v32 *)&buf[0] = v32_make('n', 'u', 'l', 'l');
+ return buf + 4;
}
}
@@ -5779,7 +5780,8 @@ static_noinline u8 *write_f64_raw(u8 *buf, u64 raw, bool allow_nan_and_inf) {
return buf + 3;
}
} else {
- return NULL;
+ *(v32 *)&buf[0] = v32_make('n', 'u', 'l', 'l');
+ return buf + 4;
}
}
}
vc6.0 mfc project
The dll module introduces yyjson and creates a method of write string
.exe module uses methods in the dll module
Dlls compile alone without problems, .exe compilation prompts
JsonTest.obj : error LNK2001: unresolved external symbol _yyjson_mut_doc_free
JsonTest.obj : error LNK2001: unresolved external symbol _yyjson_mut_doc_new
JsonTest.obj : error LNK2001: unresolved external symbol _yyjson_mut_write_opts
JsonTest.obj : error LNK2001: unresolved external symbol _unsafe_yyjson_val_pool_grow
Debug/JsonTest.exe : fatal error LNK1120: 4 unresolved externals
What should I do?
Describe the bug
A clear and concise description of what the bug is.
Your environment
Additional context
Add any other context about the problem here.
`
--------------------Configuration: testyyjson - Win32 Debug--------------------
Compiling...
yyjson.c
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(2534) : error C2485: 'noinline' : unrecognized extended attribute
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(2717) : error C2485: 'noinline' : unrecognized extended attribute
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(4020) : error C2485: 'noinline' : unrecognized extended attribute
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(5181) : error C2485: 'align' : unrecognized extended attribute
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(5181) : error C2059: syntax error : '('
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(5594) : error C2485: 'noinline' : unrecognized extended attribute
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(5604) : warning C4244: '=' : conversion from 'unsigned __int64 ' to 'unsigned int ', possible loss of data
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(5888) : error C2485: 'align' : unrecognized extended attribute
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(5888) : error C2059: syntax error : '('
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(5957) : error C2485: 'align' : unrecognized extended attribute
c:\documents and settings\administrator\桌面\testyyjson\yyjson.c(5957) : error C2059: syntax error : '('
执行 cl.exe 时出错.
testyyjson.exe - 1 error(s), 0 warning(s)
`
In py_yyjson, I've added JSON Pointer support which includes the ability to patch the value at the pointer with another yyjson_mut_val. However, I noticed that removal doesn't automatically free a value, and there appears to be no explicit API to free a value.
This seems to be by design - the pool for a mutable doc can only be created, grown, or freed in its entirety. There's nothing wrong with this approach, but it should be documented that values, once created, cannot be destroyed. Thus yyjson_mut_doc is more suitable for write-once, than mutation of an existing document.
Is your feature request related to a problem? Please describe.
I can't find how to get the key of the yyjson_mut_val,is there any functions to get the key ?
Describe the solution you'd like
can sombody add get key functions to yyjson lib?
Describe alternatives you've considered
as we known,json is key/value based protocol, Get the key name is an very important function to json libs.
Additional context
Add any other context or screenshots about the feature request here.
What's the best way to rename a key in a json object?
Describe the bug
A clear and concise description of what the bug is.
二级对象下的逗号会导致json无法解析,虽然我知道这不符合json规范
{"objet":["ooject1":123,"ooject2":123,"ooject3":123,]}
Your environment
Additional context
Add any other context about the problem here.
Describe the bug
With this example program:
#include "yyjson.h"
int main(int argc, char const *argv[]) {
// Create a non-delimited string
char my_string[20];
for (int i = 0; i < 20; i++) {
my_string[i] = 'a';
}
// Create a doc with this string as a key/value pair
yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL);
yyjson_mut_val *obj = yyjson_mut_obj(doc);
yyjson_mut_val *val = yyjson_mut_strn(doc, my_string, 20);
yyjson_mut_obj_add(obj, val, val);
yyjson_mut_doc_set_root(doc, obj);
// Write the doc
size_t len;
char *json = yyjson_mut_write(doc, 0, &len);
return 0;
}
Compiled with cc -fsanitize=address -o my_string_test my_string_test.c yyjson.c
I ran ./my_string_test
, which should finish normally.
Instead we get undefined behaviour AddressSanitizer: stack-buffer-overflow ...
and so on.
This can be fixed by adding
if (end - str < 16)
goto copy_next;
to yyjson.c:6380
. You may have a better idea about how to fix this more efficiently though, so I decided not to send a PR :)
Your environment
Additional context
I am using yyjson to create a JSON extension for DuckDB. Your library is amazing! Many thanks.
{
"0":{
"one":"text"
}
}
and add to it
{
"1":{
"one":"text"
}
}
to become
{
"0":{
"one":"text"
}
"1":{
"one":"text"
}
}
Great lib with bad doc =(
The header file yyjson.h
has multiple issues when compiling with -Wundef
compiler option on GCC or clang.
There are missing check if _MSC_VER
or __GNUC__
or other flags are defined before checking them.
Example lines:
https://github.com/ibireme/yyjson/blob/master/src/yyjson.h#L127
https://github.com/ibireme/yyjson/blob/master/src/yyjson.h#L131
https://github.com/ibireme/yyjson/blob/master/src/yyjson.h#L168
https://github.com/ibireme/yyjson/blob/master/src/yyjson.h#L177
https://github.com/ibireme/yyjson/blob/master/src/yyjson.h#L187
https://github.com/ibireme/yyjson/blob/master/src/yyjson.h#L205
I found there is an API yysjon_mut_read_file
in readme. But it doesn't exist in yyjson.h
. Should I copy yyjson_doc as yyjson_mut_doc every times?
Hi!
I was just testing the library for the first time and couldn't find a way to parse something like the following:
{"people": [ {"name":"Alice", "age": 40}, {"name": "John", "age": 38} ]}
Is there a (optimal) way to do it?
Can you please provide an example on how to just iterate over multiple objs inside the array and print the "name" and "age"?
Thank you in advance!
As mentioned in #79, yyjson_val_write_opts
and yyjson_mut_val_write_opts
should include
#if YYJSON_DISABLE_NON_STANDARD
flg &= ~YYJSON_WRITE_ALLOW_INF_AND_NAN;
#endif
like it is done in reader functions.
Currenly just adding this block is not enough, the tests don't check the YYJSON_DISABLE_NON_STANDARD
before testing writer with YYJSON_WRITE_ALLOW_INF_AND_NAN
flag.
Hi!
Your library is great! But one thing I couldn't find is how to serialize and deserialize arrays of objects, as well as nested objects. I saw that you have a couple of closed tickets regarding how to work with arrays of objects, so I believe that explaining it in the documentation will help a lot.
My main use for this library would be to dump arrays of C structs (and sometimes a struct can have another array of structs nested inside it)... so documentation about this would be very welcome!
Please use English to communicate so that people from other countries can understand it.
i heared about memcpy when copy little string is slower than =
because of the memcpy use call instrustion.
on my computer memcpy 2 is slower than "repeat2_incr"
memcpytest.txt
Hi,all:
Is there any way to make yyjson easily to use for serialization and deserialization, for example, can i get the info like nlohmann json or through python-style rather than through the complex parsing ways. Or how can I rewrite it, Thx.
Describe the bug
full repro
#include <stdio.h>
#include <string.h>
#include <yyjson.h>
int main()
{
char json[] = "{\"alg\":\"ES256\",\"typ\":\"JWT\"}\0\0\0\0\0";
char BUF[32]; // change me to >= 64 and I won't crash
yyjson_alc json_alc;
yyjson_alc_pool_init(&json_alc, BUF, sizeof(BUF));
yyjson_doc* doc = yyjson_read_opts(json, strlen(json), YYJSON_READ_INSITU, &json_alc, NULL);
if (!doc) {
printf("OOM\n");
return -1;
}
const char* alg = yyjson_get_str(yyjson_obj_get(yyjson_doc_get_root(doc), "alg"));
printf("%s\n", alg);
return 0;
}
Stack:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x0000000000429c76 in read_root_minify (err=0x7fffffffa130, flg=1, alc=..., end=0x7fffffffd61b "", cur=0x7fffffffd600 "{\"alg\":\"ES256\",\"typ\":\"JWT\"}", hdr=0x7fffffffd600 "{\"alg\":\"ES256\",\"typ\":\"JWT\"}") at src/yyjson.c:4705
#2 yyjson_read_opts (dat=0x7fffffffd600 "{\"alg\":\"ES256\",\"typ\":\"JWT\"}", len=27, flg=1, alc_ptr=0x7fffffffd5c0, err=0x7fffffffa130) at src/yyjson.c:5535
#3 0x00000000004012ce in main () at crash.c:12
If BUF
's size is 64
then we correctly get a NULL
document.
Your environment
Additional context
Reproduces on ee9e6d5d3bde4a26b78e9cfd596dd28d231266fa
Hello,my input string structure is like this:
[{"addition":{"barcode":{"barcode":"78209172869467","position":[{"x":"1509","y":"1797"},{"x":"1213","y":"1518"},{"x":"1179","y":"1555"},{"x":"1475","y":"1833"}]},"threecode":["341;7-13;002","341;7-13;004"...]},"extend":"","filename":"/home/linaro/78209172869467.jpg","image":{"colorspace":"RGB","encodeData":"/9j/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/wAARCAvcD7gDASIAAhEBAxEB/9oADAMBAAIRAxEAPwD49HWg9KDRj1oAB69KXj60YpO9AAelL3pDz9aKACl70DHNIfXHNAC4xSduKU84pB3FACjqPejNJ6Gl45oAWkFHUUDr60AHaj8aT1FL2oAPWjPFAo7UAL3NAAK+lNpV70AHeg9KD2p3G09c0ANPSgcUp6e9J1OKAEpW4IOaDRxgUAKOh5pD1FKO4pD9aAF74pB0FHf8KXsaADvSHuKO4NKw560AJ2BpV69KQA4oHWgAPalI5pD0pc9KADsRSdxSjuOhpD0oAD1NA6ClIAPNIBwaAAdaSl6EdqPUUALSd6UdKP4qADqKMYOBR60fWgBV5BpD1BoHUikPIoAX1oHQUHrQOlAB1ag9KO9LjrQAnpRjGaB0FH8VAB2BpR3pO1KOooAQfdo70oHUdM0dgaAE9RR6Up+8cUfwmgA6tikwcc0vejHWgA46igdxR2Bo/iNACenpTj1pp6daUdeaAAfdoHWgYAIoPbFAAR1oPOKG6mkHSgBV6mjsMcUDqKD3FACnqKQc5o9OvNB6mgAx0JpzfePpTe2aXvQAnb6Uv8VC9DSDqKADpkUvpQOpo/gH1oAQcEilwMZ70d+vakPQjFADj..."}}]
anyone knows how to parse this kind of input using yyjson,Thx a lot! the grammar was not easy for newer.
有没有计划支持直接解析wchar_t,就像rapidjson一样?
Describe the bug
compile error
Your environment
Additional context
In file included from test.c:1:0:
yyjson.h:260:53: error: conflicting declaration ‘typedef long long int int64_t’
__extension__ typedef long long int64_t;
^
In file included from /usr/include/stdlib.h:314:0,
from yyjson.h:18,
from test.c:1:
/usr/include/sys/types.h:197:1: error: ‘int64_t’ has a previous declaration as ‘typedef long int int64_t’
__intN_t (64, __DI__);
^
绿帽子节 to \u7EFF\u5E3D\u5B50\u8282
I run it on iOS
I'm planning on implementing this and would like your feedback.
Python supports arbitrarily large numbers (both integers and floats), and it would be nice to be able to support that with JSON input/output as well (as an optional flag, so by default it should raise an error).
I'd add support for this into yyjson as part of the work on py_yyjson by implementing a YYJSON_TYPE_UNQUOTED
type. When reading, it parses until the end of a number and stores it in the string pool. Using this replaces all number parsing.
When writing, it's dumped as-is. Because it's not number specific, I've made it its own type instead of a numeric SUBTYPE. It's actually fairly useful for special cases, such as when I have a known-good JSON snippet I want to just sub in as an object value.
There are some issues I found when checking yyjson with cppcheck
.
Line 4156 in 94e47ab
pre_key
is useless, since it's never used.
Lines 4129 to 4130 in 94e47ab
Lines 6560 to 6562 in 94e47ab
goto
or return
are unreachable. repeat16_incr
will never be executed.
Line 5524 in 94e47ab
(file_size + 1) < 0
is always false. If you wanted to check for long
overflow then this is undefined bahaviour (signed integer overflow is UB).
Line 5482 in 94e47ab
hdr
is always not NULL
, since it's checked after malloc
.Do you have an example of this?
https://stackoverflow.com/questions/54210389/is-there-a-generic-way-to-read-the-multiline-json-in-spark-more-specifically-sp
Given the length of a json string, what is the upper bound on the size of a pool alc that could handle that json?
size_t pool_size;
yyjson_alc_pool_max_size(json_size, &pool_size);
void *buf = alloca(pool_size)
yyjson_alc alc;
yyjson_alc_pool_init(&alc, buf, pool_size);
Describe the bug
compile error on CentOS 6.10.
Your environment
Additional context
[root@localhost build]# cmake --build .
Scanning dependencies of target yyjson
[ 50%] Building C object CMakeFiles/yyjson.dir/src/yyjson.c.o
In file included from /home/yyjson-0.3.0/src/yyjson.c:9:
/home/yyjson-0.3.0/src/yyjson.h:298: error: conflicting types for ‘int64_t’
/usr/include/sys/types.h:198: note: previous declaration of ‘int64_t’ was here
/home/yyjson-0.3.0/src/yyjson.h:353: warning: expected [error|warning|ignored] after ‘#pragma GCC diagnostic’
/home/yyjson-0.3.0/src/yyjson.h:3900: warning: expected [error|warning|ignored] after ‘#pragma GCC diagnostic’
/home/yyjson-0.3.0/src/yyjson.c:26: warning: expected [error|warning|ignored] after ‘#pragma GCC diagnostic’
/home/yyjson-0.3.0/src/yyjson.c:7213: warning: expected [error|warning|ignored] after ‘#pragma GCC diagnostic’
gmake[2]: *** [CMakeFiles/yyjson.dir/src/yyjson.c.o] Error 1
gmake[1]: *** [CMakeFiles/yyjson.dir/all] Error 2
gmake: *** [all] Error 2
[root@localhost build]#
Since I saw your illness on your blog, there has been no news about you. I am very happy to see your newly created Repo. All recovered now ?
Is your feature request related to a problem? Please describe.
It would be nice if we could have public APIs to initialize yyjson_mut_val
stack objects that we could then pass along to yyjson_mut_obj_add
/ yyjson_mut_arr_append
. That's because most of the time, the responses are simple and static enough for this to work.
Describe the solution you'd like
Say for instance I want to build:
{code: 5, params: [1, "error-msg"]};
it would be nice if I could do it with no allocations
yyjson_mut_val root, code_key, code_val, params_key, params_arr, one, msg;
/*
* start of missing API
*/
yyjson_mut_set_obj(&root);
yyjson_mut_set_str(&code_key, "code_key");
yyjson_mut_set_int(&code_val, 5);
yyjson_mut_set_str(¶ms_key, "params");
yyjson_mut_set_arr(¶ms_arr);
yyjson_mut_set_int(&one, 1);
yyjson_mut_set_str(&msg, "error-msg");
/*
* end of missing APIs
*/
// we can already do those
yyjson_mut_obj_add(&root, &code_key, &code_val);
yyjson_mut_obj_add(&root, ¶ms_key, ¶ms);
yyjson_mut_arr_append(¶ms, &one);
yyjson_mut_arr_append(¶ms, &msg);
char buf[100];
// ....
yyjson_mut_val_write_opts(&root, &alc ....);
Describe alternatives you've considered
I guess tags could be set manually on the struct instances, but tags are advertised as being part of the private API.
Describe the bug
The first array of objects with unrecognized infos
Your environment
Additional context
json
{
"infos": [
{
"names": [
"a",
"b",
"c"
]
},
{
"names": [
"d",
"e",
"f",
"g"
]
}
]
}
code
yyjson_read_flag flag = YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS;
yyjson_read_err err;
yyjson_doc *doc = yyjson_read_file("data.json", flag, NULL, &err);
if (doc) {
yyjson_val *root = yyjson_doc_get_root(doc);
yyjson_val *infos = yyjson_obj_get(root, "infos");
if (yyjson_is_arr(infos)) {
printf("infos.size=%zu\n", yyjson_arr_size(infos));
yyjson_val *val1;
yyjson_arr_iter iter1;
yyjson_arr_iter_init(infos, &iter1);
while ((val1 = yyjson_arr_iter_next(&iter1))) {
if (yyjson_is_obj(val1)) {
yyjson_val *names = yyjson_obj_get(val1, "names");
if (yyjson_is_arr(names)) {
yyjson_val *val2;
yyjson_arr_iter iter2;
yyjson_arr_iter_init(names, &iter2);
while ((val2 = yyjson_arr_iter_next(&iter2))) {
printf("%s\n", yyjson_get_str(val2));
}
} else {
printf("type=%d\n", yyjson_get_type(names));
}
}
}
}
} else {
printf("read error (%u): %s at position: %zu\n", err.code, err.msg, err.pos);
}
yyjson_doc_free(doc);
result
infos.size=2
type=0
d
e
f
g
desired result
infos.size=2
a
b
c
d
e
f
g
Describe the bug
Hi!
Your library is great! But when I parse a json file like:
[
{}, {}, {}
]
yyjson_read_file() is success , but get root obj failed, eg. obj = yyjson_doc_get_root(doc) , the test json data generated by
http://www.yyyweb.com/demo/inner-show/json-generator.html?spm=a2c6h.12873639.article-detail.10.55ca4246qH5YKd
just use default config. (todo: try use arr api maybe work!)
Hi ibireme
Thank you very much for your last reply, but I found a problem, please help me to solve it, and I look forward to your reply
//How to find yyjson_mut_val* according to key
yyjson_mut_val* getOrCreateChildMutObj(yyjson_mut_doc doc, yyjson_mut_val parent, const std::string &key)
{
yyjson_mut_val* child = yyjson_mut_get_pointer(parent, key.data());
if (!child)// if not find, build key/value
{
child = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, parent, key.data(), child);
}
return child;
}
//How to find array nodes(yyjson_mut_val*) based on key ?
yyjson_mut_val* getOrCreateArray(yyjson_mut_doc *doc, yyjson_mut_val arryParent, const std::string &key)
{
yyjson_mut_val arry = yyjson_mut_get_pointer(arryParent, key.data());
if (!arry)
{
arry = yyjson_mut_arr(doc);
yyjson_mut_obj_add_val(doc, arryParent, key.data(), arry);
}
return arry;
}
void funcLayout(yyjson_mut_doc *doc)
{
std::string key1("PATH_KEY_NODE");
std::string key2("INFO_KEY_NODE");
//case 1
{
// auto val = getOrCreateChildMutObj(doc, doc->root, key1);
// yyjson_mut_val* layoutKeyNode = getOrCreateChildMutObj(doc, doc->root, key2);
//output: It seems something went wrong
/*
{
"???\"m�\u0000\u0000?K\u0001\u0000": {},
"INFO_KEY?????�": {}
}
*/
}
//case 2
{
yyjson_mut_val* child = yyjson_mut_get_pointer(doc->root, key1.data());
if (!child)
{
child = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, doc->root, key1.data(), child);
}
yyjson_mut_val* child1 = yyjson_mut_get_pointer(doc->root, key2.data());
if (!child1)
{
child1 = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, doc->root, key2.data(), child1);
}
//output: Should be correct
/*
{
"PATH_KEY_NODE": {},
"INFO_KEY_NODE": {}
}
*/
}
}
void writeJson()
{
yyjson_mut_doc *doc = yyjson_mut_doc_new(nullptr);
yyjson_mut_doc_set_root(doc, yyjson_mut_obj(doc));
funcLayout(doc);
//funcVerify(doc);
yyjson_write_flag flg = YYJSON_WRITE_PRETTY /*| YYJSON_WRITE_ESCAPE_UNICODE*/;
yyjson_write_err err;
yyjson_mut_write_file("config.json", doc, flg, nullptr, &err);
yyjson_mut_doc_free(doc);
}
////////
1、The result of calling at the very beginning of the program is correct
int main(int argc, char *argv[])
{
writeJson(); //The result of calling at the very beginning of the program is correct
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
2、The result of this call is wrong
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
writeJson(); ///////////
return a.exec();
}
//////////////////////////////////
The output result of my case 2 method should be correct, but the output result of case 1 seems to be wrong. Can't you use function calls? There is still a problem with the method I use. Looking forward to your reply, thank you
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::string key1("LAYOUT_PATH_KEY_NODE");
std::string key2("VERIFY_KEY_NODE");
std::string input("input_layout");
std::string output("output_layout");
std::string outlevel("output_level");
//case 1
{
yyjson_mut_val* child1 = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, doc->root, "ROOT", child1);
getOrCreateChildMutObj(doc, child1, "key2");
getOrCreateChildMutObj(doc, child1, "key23");
yyjson_mut_val* layoutKeyNode = getOrCreateChildMutObj(doc, child1, key1);
yyjson_mut_val* arryNode = getOrCreateArray(doc, layoutKeyNode, outlevel);
//Is there a problem with inserting data like this???
std::vector<std::string> v{"kkkkk33333", "wwwwwwwwww", "rrrrrrrrrr", "qqqqqqqqqqqqq"};
for(size_t i = 0; i < v.size(); ++i)
yyjson_mut_arr_add_strcpy(doc, arryNode, v[i].data());
#This way of access is correct, but how do I want to dynamically insert data?
// yyjson_mut_arr_add_strcpy(doc, arryNode, "yyyyyyy");
// yyjson_mut_arr_add_strcpy(doc, arryNode, "out/debug/bin/config.json");
// yyjson_mut_arr_add_strcpy(doc, arryNode, "out/debug/bin/config2.json");
// yyjson_mut_arr_add_strcpy(doc, arryNode, "ttxttttt");
}
output:
"ROOT": {
"key2": {},
"key23": {},
"LAYOUT_PATH_KEY_NODE": {
"�\u0000\u0000\u0000\u0000\u0000\u0000\u0000�\u0000\u0000\u0000": [
"kkkkk33333",
"wwwwwwwwww",
"rrrrrrrrrr",
"qqqqqqqqqqqqq"
]
}
}
Hi ibireme
how do I want to dynamically insert data?
for example :
std::vectorstd::string v{"kkkkk33333", "wwwwwwwwww", "rrrrrrrrrr", "qqqqqqqqqqqqq"};
yyjson_mut_val* arryNode; //obj or arry
for(size_t i = 0; i < v.size(); ++i)
yyjson_mut_arr_add_strcpy(doc, arryNode, v[i].data());
The file name suffix is .cpp, then compile with g++ ,Can I use g++ to compile?
It's fairly typical to want to extract just part of a document, then write it out. However, there's no current way to print a subset of a document without getting the value, making it the new root, and then writing the entire document.
Ex: Writing the result of a json_merge_patch()
, or writing the result of a yyjson_mut_get_pointer()
.
The yyjson_obj_getn function requires linear search time when searching. Whether to consider increasing the range and limiting the start position and end position of the search, so that all node traversals caused by expandable fields can be avoided during use.
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.