If you try #including libjson_spirit_writer_template.h in a project outside the JSON Spirit tree on a Linux box, it fails because libjson_spirit_writer_options.h isn't installed in /usr/local/include. The fix is trivial. Add:
Hi John,
first thank you for a wonderful product, it was a pleasure to use it.
I have noticed a small problem in a writer part:
if json data contains something like
"name": "\u05DE\u05E9\u05EA\u05DE\u05E9 \u05E8\u05D0\u05E9\u05D5\u05DF"
the unicode string is correctly parsed with son_spirit::read( std::wistream& is, wmValue& value ).
From the other hand, writing the parsed data write or write_formatted either produces a broken json.
I think that adding the following default case to the switch in
json_spirit::add_esc_char( Char_type c, String_type& s ) fixes this behavior:
John, I was rather perturbed that when writing a largish (~200 nodes) and deep object tree it was taking 2.5 seconds. I investigated and found that excessive implicit copy constructors were being invoked when descending through each object. The problem exists for both vector and map versions but was worse for map (mObject). The fixes are as follows and are partly due to an incorrect const qualified typedef and functions returning by value instead of const reference
In json_spirit_value.h in struct Config_map
typedef std::pair< String_type, Value_type > Pair_type; should be typedef std::pair< String_type const, Value_type > Pair_type;
Note the added const qualifier - to see why look up any std::map documentation. This was resulting in a compiler forced copy to honour the (lack of) const on the std::map key type
This fix should also be applied to the get_name and _get_value functions in Config_vector
The above was causing the following function in json_spirit_writer_template.h to copy a full JSON sub tree into both get_name and get_value and return yet another copy from get_value
void output( const Obj_member_type& member )
{
output( Config_type::get_name( member ) ); space();
os_ << ':'; space();
output( Config_type::get_value( member ) );
}
thank you and congratulations for this library. Thanks to it, I managed to export a huge bunch of datas from a legacy monolithic code to a pretty fine json file, in a few hours of work. Same for reading stuffs. jason_spirit made me win a lot a time, thank you once again.
Fabulous work done by you sir......
Sir what i want to do is to take the JSON OBJECT as argument that i get from one of my method of C# DLL an parse it and store it in a file.
Can you tell which projects do i have to use and is there any change do i have to make?
I encounter problem with read/write of real numbers.
e.g.
the original value is 2.2086570657060003, and in "write" it is truncated to 2.208657065706.
Since my program doesn't manipulate the nodes of numbers at all, I want to add to the parser the option to remember the string representation of double value.
Namely treat doubles as strings, and in this way avoid any real numbers issues.
Is there a simple way to do it ?
I've put a breakpoint in the constructor of double Value, and the stack is quite deep with all the spirit scanner/parser/rules/policies etc. so I don't know if it's possible at all, or where to start.
Any help is appreciated, or other idea to solve the problem.
10x.
So even though javascript and c++ both define nan and infinity the JSON standard has deliberately left out support for them.
The ECMAScript Programming Language Standard describes how these values are to be handled in the section on JSON Lexical Grammar, specifically on page 208 in Note 4 stating: "Finite numbers are stringified as if by calling ToString(number). NaN and Infinity regardless of sign are represented as the String null."
Currently JSON Spirit when given a nan or inf as a double value will write out the nan or inf directly (e.g.: {"value_name": nan}). This results in an error in the JSON formatting.
My suggestion is to handle nan's and inf's by either following the standard in the ECMAScript PL Standard and convert these values to null's or throw a runtime_error when these values are detected. Here's a diff from a small change that I implemented:
I tried to install JSON Spirit v 4.05 on Ubuntu 10.10. I think that it does not install correctly the "json_spirit_writer_options.h" file.
To solve it, I modified the CMakeLists.txt file (it works now). I do not know if I am missing something. Here it goes the new file , just in case anybody finds it useful (changes in boldface):
I compile the json-spirit v4.5 under the linux environment and follow the instruction
which cmakereadme.txt provides.
But one thing I am not sure about is how to set the boost root.
I am relavtive new to linux. so sorry ask a very simple and basic question.
And the following message is the terminal shows
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc
-- works -- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++
-- works -- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.48.0
-- Found the following Boost libraries:
-- Configuring done
-- Generating done
/*********************************************************************************/
/*************************************************************************************/
-- Install configuration: -- Installing:
/usr/local/include/json_spirit.h -- Installing:
/usr/local/include/json_spirit_error_position.h -- Installing:
/usr/local/include/json_spirit_reader.h -- Installing:
/usr/local/include/json_spirit_reader_template.h -- Installing:
/usr/local/include/json_spirit_stream_reader.h -- Installing:
/usr/local/include/json_spirit_utils.h -- Installing:
/usr/local/include/json_spirit_value.h -- Installing:
/usr/local/include/json_spirit_writer.h -- Installing:
/usr/local/include/json_spirit_writer_template.h -- Installing:
/usr/local/lib/libjson_spirit.a
/********************************************************************************/
Is that ok when I didn't change any thing that cmake instruction provide
and compile it to the static library as long as I already include and set up the boost libray in my project then I can just include the static libray libjson_spirit.a and using it?
I am using the Eclipse CDT under linux ubuntu.
And the final question is that does I need to include the every staic boost library that shows when I using ./bjam --show-libaries that list when I using the json-spirit
I build boost library in the usr/local/lib/ and usr/local/include/ but I am not sure which boost sub static library should I add in the -l library variable so basiclly I just add in every thing that ./bjam -libraries shows: ex boost_regx , boost_filesystem and so on...
I notice that here is a similar question that ask before,but after read it I still kind of confusing.Thanks for reading and answering my qusetion in advanced.
This JSON lib is great. Love it. But the error messages in exceptions are opaque "value type is 2 not 4"
How about: "The requestet type 'string' does not match the real type 'int'.
Not all people that are using a program which embeds the JSON lib will have access to the code to see what kind of value type 4 is.
Hello
I try to use the json_spirit to convert my struct to json and save it on the local disk.But there is an LINK 2019 error when I compiled in DEBUG,said
The JSON spirit performance will be greatly improved if you can eliminate creating sparser engine (Json_grammer< Value_type, Iter_type >( semantic_actions )) repeatedly.
At this time, you set grammar whenever you make a parse, which degrades parsing performance.
Is a nice feature, maybe adding a few directives at compile time to choose map types.
I mean, its nice to have object[name]=value sintax on unordered container with no duplicates.
Its useful on my project were I only need to write_build json from other data.
There's problem in JSON Spirit library with deserializing JSON with literal \uHHHH in string version (wstrings work fine). In json_spirit_reader_template.h is part of code to decode \uHHHH literal to char. If we use string, value_type is char, so literal is converted to one byte (literal contains two bytes of information) but should be converted to one, two or three bytes (depends on literal value). For my purposes I wrote simple fix and unicode_str_to_char function is no longer conversion to char, but to string. In this code is ugly line - condition based on size of Char_type to recognize if function is used to wstring or to string. Here is code fixing that issue:
Of course we must change line where function is called too:
case'u':
{
if( end - begin >= 5 ) // expecting "uHHHH..."
{
s += unicode_str_to_decoded_str< String_type >( begin );
}
break;
}
default: break;
EDIT: Similar problem is with writer too. JSON Spirit (when we use string, wstrings are OK) serilize every unicode character into 1, 2 or 3 literals \uHHHH instead of to 1 literal. Below is patch changing add_esc_chars function in json_spirit_writer_template.h:
template< class String_type >
String_type add_esc_chars( const String_type& s, bool raw_utf8 )
{
typedeftypename String_type::const_iterator Iter_type;
typedeftypename String_type::value_type Char_type;
String_type result;
const Iter_type end( s.end() );
for( Iter_type i = s.begin(); i != end; ++i )
{
const Char_type c( *i );
if( add_esc_char( c, result ) ) continue;
if( raw_utf8 )
{
result += c;
}
else
{
wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c );
// iswprint does not work fine for UTF-8 on Windows
if ((unsigned_c >= 0x20) && (unsigned_c < 0x7f)) // 0x20 = 0b00100000; 0x7f = 0b01111111
{
result += c;
}
else
{
/* \u0000 to \u007F is converted to 1 byte (0xxxxxxx)
\u0080 to \u07FF is converted to 2 bytes (110xxxxx 10xxxxxx)
\u0800 to \uFFFF is converted to 3 bytes (1110xxxx 10xxxxxx 10xxxxxx) */if (unsigned_c >= 0x80) // 0x80 = 0b10000000
{
if (unsigned_c < 0xe0) // 0xe0 = 0b11100000
{
++i;
if (i == end)
{
throw std::runtime_error( "incorrect string" );
}
const Char_type c2( *i );
const wint_t unsigned_c2( ( c2 >= 0 ) ? c2 : 256 + c2 );
unsigned_c = ((0x1f & unsigned_c) << 6) | // 0x1f = 0b00011111
(0x3f & unsigned_c2); // 0x3f = 0b00111111
}
else
{
++i;
if (i == end)
{
throw std::runtime_error( "incorrect string" );
}
const Char_type c2( *i );
const wint_t unsigned_c2( ( c2 >= 0 ) ? c2 : 256 + c2 );
++i;
if (i == end)
{
throw std::runtime_error( "incorrect string" );
}
const Char_type c3( *i );
const wint_t unsigned_c3( ( c3 >= 0 ) ? c3 : 256 + c3 );
unsigned_c = ((0x0f & unsigned_c) << 12) | // 0x0f = 0b00001111
((0x3f & unsigned_c2) << 6) | // 0x3f = 0b00111111
(0x3f & unsigned_c3); // 0x3f = 0b00111111
}
}
result += non_printable_to_string< String_type >( unsigned_c );
}
}
}
return result;
}
If someone use JSON Spirit in string version and has problem with \uHHHH literals above "patch" should fix the problem.
Hello,
I need to read a very large json file into mobile device (android) with a small memory footprint. I would like to use a "streaming read", where I sequentially work my way through a file only pulling in the data I need in a sequential fashion. In other words, I have thousands of data entries in the json file that I need to feed into a routine one by one; at no time do need to global access, just sequential access. I've used the gson library (java) which provides this, but now I need to reimplement in C++.
I've read the JSON Spirit docs, but I'm having trouble figuring out whether the reads are global or sequential.
Is JSON Spirit the right choice? If not, can you recommend another library?