Using json_spirit v4.04, I ran into a bug when using the json_spirit::write function with the remove_trailing_zeros flag. Doubles that have a fractional part equal to zero are returned as the integer part followed by a decimal (e.g. 3.0 => 3.). This creates invalid JSON syntax. Here is a small test program:
#include <stdio.h>
#include <json_spirit.h>
int main(int argc, char **argv) {
double f = 3.0;
std::string s;
json_spirit::mObject obj;
obj["foo"] = f;
s = json_spirit::write(obj, json_spirit::remove_trailing_zeros);
printf("%s\n", s.c_str());
return0;
}
I am new in C++. I came from C# and Java world. I tried the example and it`s working perfectly when I used that in Microsoft Visual Studio 2010. But, I expended two days and I couldn't do the same in Eclipse Indigo over Linux Ubuntu.
If someone has already used this codeproject example on Eclipse/Linux and could give some suggestion about make the example work on Eclipse/Linux, it will be nice as well.
While writing simple object types to wstring works perfectly, trying to write values of type object or array fails, since it converts start and end characters '{', '[', '}', ']' to numbers.
I just read this stunning testimony of the guy that develops the Epoch language. And he experienced a speedup of a factor of 1'000 by switching to Spirit.Qi!
Would be nice if you could try to tune your lib too, because we want to use it in a Webservice where speed is king. And thanks for maintaining the code for so long
/Users/jason/src/agent/source/sup/softbus.h
In file included from /Users/jason/src/agent/common/inc/boost/boost/spirit/include/classic_multi_pass.hpp:11 ,
from /Users/jason/src/agent/common/inc/json-spirit-4.04/json_spirit_reader_template.h:21,
from /Users/jason/src/agent/source/sup++/sup++.h:14,
from /Users/jason/src/agent/source/sup/softbus.h:154:
/Users/jason/src/agent/common/inc/boost/boost/spirit/home/classic/iterator/multi_pass.hpp:198:9: error: expected unqualified-id before '{' token
Seems to be conflicting with something in boost. This is with gcc 4.5.2, using the latest boost libraries of this writing. Same code builds fine on windows with visual studio 2010.
Thank you for the piece of code that has already saved me hours of hard work
I have one suggestion on the way arrays and objects are printed.
They can be either 'pretty' (with white characters) or 'ugly' (with no white characters).
What you might want to consider is a way to print everything as 'pretty' and only arrays or objects as 'ugly.'
This would enable output similar to this one:
{
"0" : [ 0, 0, 0, 0, 0 ],
"1" : [ 0, 1, 2, 3, 4 ],
"2" : [ 0, 2, 4, 6, 8 ],
"3" : [ 0, 3, 6, 9, 12 ],
"4" : [ 0, 4, 8, 12, 16 ]
},
which in my opinion is prettier than the 'pretty_print' output, since it is more readable and can emulate the layout of 2D arrays.
I have a modified (backward-compatible) 'json_spirit_write_template.h' file that is capable of producing the above output (write function accepts two additional options: 'ugly_array' and 'ugly_object').
I could post it if you are interested.
Of course the possibility to print 2D arrays in a form:
[
[ 0, 0, 0, 0, 0 ],
[ 0, 1, 2, 3, 4 ],
[ 0, 2, 4, 6, 8 ],
[ 0, 3, 6, 9, 12 ],
[ 0, 4, 8, 12, 16 ]
]
would be even better, but requires more severe changes to the code, so I did not try that yet.
Cheers
Is there a way you might update to allow output of fixed-length reals? It is easy enough to patch, but it would be better to use the standard version without patches.
Hi, First of all, thanks John for this marvelous library. It's very well done and we use it a lot in our web oriented projects.
Today, I'm using your code on a powerpc target and the compiler emits a warning/error that I think is related to json_spirit.
obj/include/boost/variant/recursive_wrapper.hpp: In constructor 'gui_backend::request_handling::BasicRequest::BasicRequest(const std::string&, const std::string&, const std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)': obj/include/boost/variant/recursive_wrapper.hpp:84: error: dereferencing pointer '<anonymous>' does break strict-aliasing rules obj/include/boost/variant/detail/cast_storage.hpp:33: note: initialized from here obj/include/boost/variant/recursive_wrapper.hpp:84: error: dereferencing pointer '<anonymous>' does break strict-aliasing rules obj/include/boost/variant/detail/cast_storage.hpp:33: note: initialized from here
Little context: - BasicRequest is one of my classes, it contains a RequestInfo - RequestInfo is another of my classes which contains a json_spirit::mValue as one of its members - only json_spirit is using boost::variant and recursive_wrapper in my project (so the link was easily made) - I'm compiling against boost 1.46.1 with all warnings enabled and warnings turned into errors - cast_storage is casting a void* into a T* - line 84 of recursive wrapper is a call to boost::checked_delete of the contained pointer
I can't precisely track the aliasing problem the compiler sees because boost::variant is such a mystery to me but obviously, something does not work for that compiler.
It would be good to have simple Value and Array constructor from boost::variant. As I know it can easily be done by writing boost::static_visitor<Value>, boost::static_visitor<Array> what do you think? If it is a good idea I can do it (I need it anyway) and provide patch.
Hi,
I am trying to compile the code on 64 bit ubuntu but the building process never completes. It works fine on 32 bit machine. Am I doing something wrong.
The http://www.json.org/[^] mentions that even forward slash must be escaped. Which json_spirit doesn't seem to be doing.
I encountered problem where I had to send date of the following format to a .Net service - "\/Date(1212233230000)\/" with escaped forward slashes. But json_spirit converted that to "\\/Date(1212233230000)\\/".
I solved it by adding the following line in the function add_esc_char of the file json_spirit_writer_template.h.
case'/': s += to_str< String_type >( "\\/" ); returntrue;
If you have any suggestion. Please do update your library if you think it as appropriate.
Some parts of your article are very misleading, because you confuse Unicode (probably UTF-16/32) with std::wstring. You can have Unicode with std::string in the form of UTF-8.
I've been using json_spirit for a while, and it's great! I recently tried compiling it under MinGW's implementation of C++0x. There was only one problem:
"function" is now part of the std namespace, so whenever using _both_ "namespace boost" and "namespace std", there will be an ambiguity on "function". To fix this, lines (roughly) 450 to 454 in json_spirit_reader.c should be given the "boost::" prefix, like so:
typedef boost::function< void( Char_type ) > Char_action;
typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
typedef boost::function< void( double ) > Real_action;
typedef boost::function< void( int64_t ) > Int_action;
typedef boost::function< void( uint64_t ) > Uint64_action;
Unfortunately, I am using version 4.02 of json_spirit, and I realize that you've updated since then. I downloaded the new source (4.03), but after a quick search was unable to find the corresponding offending lines (your notes say you moved the implementation into the headers?). I'm afraid I just don't have the time for a thorough search at the moment. I will try to compile the new source this weekend, if possible.
Just wanted to give you a heads up on this. If you've already fixed it, then great! I've read that you've gotten the library to compile on VS2010. From my understanding, GCC (e.g., MinGW) has _more_ of the new standard implemented than VS, so this namespace collision may eventually show up in VS as well.
Best of luck, and thanks again for a great library!
First of all, thank you for this awesome peace of code, easy to use and very interesting to read I just point out that I had to disable gcc warnings (-Wall -Wextra) to avoid gcc to vomit on my tty Is this easy to fix ?
I am trying to use json_spirit to parse a large (~1.5gb) json structure into memory. It ran and finished without any error in 250 secs. However when I do a simple count of the internal array size it was only 10% of the actual size. I am using the mValue to store the data and boost 1.44. I think the issue is lack of memory in the system. Should the library throw any bad allocation exception when the array allocation fails?
Hi,
Consider the following piece of code: mObject test;
test["temp"] = mValue("\\uFF00");
json_spirit::write(test, cout);
The output JSON is {"temp":"\\uFF00"}
However, I want it to output the "\uFF00", not escape the \ with the extra \. I believe the specification for a string at www.json.org does allow for this - by defining a string as a collection of characters, \ being special case that must be 'u' AND 4 hex numbers etc...
P.S. I also tried test["temp"] = mValue("\u" "FF00");
In case one, the input string would have been {\, u, F, F, 0, 0, \0};
In this case, the input string would have been {\u, F, F, 0, 0, \0};
This doesn't work either. The output is: {"temp":"uFF61"} which is missing the \
P.P.S
Adding: case '\u': s += to_str< String_type >( "\\u" ); return true;
to json_spirit_writer_template.h does what I want now. I don't know if this breaks anything for wide strings. Also the reader is not modified to then parse these kinds of things properly...
modified on Wednesday, September 22, 2010 11:38 AM
JSON specifies numbers with decimal base. The json_spirit functions write and write_formatted do not set the basefield format flag of the output stream to dec. In some cases the default value seems to be hex (Linux environment, gcc). A << std::dec should fix this..
I'm running into trouble printing string data that contains null characters.
Other characters are escaped (so "\4" is correctly printed as "\u0004"), but if the string contains a null character, it is truncated at the null. I suspect this is because add_esc_chars uses an iterator to traverse the string, but I haven't looked at it closely enough to be certain.
Are you aware of this issue? Do you have any suggestions about how to work around it? My strings are plain old stl strings.
**edit**
I'm a moron. My test case was broken. json_spirit works perfectly. Sorry if you spent any time on this. =/
I know this would be non-standard but quite useful.
Support for CDATA section like in XML would allow one to store
large text e.g. sql statement without having to use messy escapes.
Alternatively, can you suggest ways one can add this feature to JSON Spirit?