|
yes, this looks OK. The UTF-8 sequences are being passed through unaltered.
I take it that the function add_esc_char(c,result) will somehow manage to handle the normal escape sequences, like \\ \" \n \t etc. (This funktion would need to have some embedded state, or inspect the rightmost character(s) of result).
But basically that's another question not realted to UTF-8 handling.
Regards,
Hermann Vosseler
|
|
|
|
|
Hi,
I'm trying to convert a small json string to map,
but with no success .
This the code I wrote:
char* res = "{\"responseData\": {\"translatedText\":\"hola mundo\"}, \"responseDetails\": null, \"responseStatus\": 200}";
Value_type value;
String_type in_s( to_str( res ) );
read_or_throw( in_s, value );
if (value.type()==obj_type)
{
Object_type obj;
obj = value.get_obj();
map<String_type,Value_type> mp_obj;
for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i )
mp_obj[ i->name_ ] = i->value_; <big></big>
}
but I get compilation error:
error C2039: 'name_' : is not a member of 'std::pair<_Ty1,_Ty2>'
Do u know what can cause the problem ?
I've added this code in
"json_spirit::test_reader, run_tests()"
10x for any help
|
|
|
|
|
I don't know what the exact type of your Object_type is. If it is a json_spirit::Object then you should not get the error. If it is a json_spirit::mObject then it is already a map and i->first is the pair's name, i->second is the pair's value.
Regards
John
|
|
|
|
|
thanks your code!
how to parse the string of {"a":1,"c" ,"dog":{"dogId":3,"isHungry" },"e":5,"exp":48810,"farmlandStatus":[{"a":34,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":26,"l":15,"m":15,"n":{"10177679":1,"16513950":1,"19783570":1,"20194034":1,"2175835":1,"25779663" ,"328410816":1,"3663649":1,"3783771":1,"41503729" ,"41892699" ,"43477953" ,"4469715" ,"532102" ,"538815525":1,"649460555" ,"8374675":1},"o" ,"p":[],"q":1260201288,"r":1260489476},{"a":55,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":28,"l":16,"m":16,"n":{"125462791":1,"13331147":1,"16513950":1,"2175835" ,"25779663":1,"294887051":1,"328410816" ,"3663649" ,"3783771" ,"41403882" ,"41503729" ,"41892699":1,"43477953":1,"4469715" ,"63322968":1,"649460555" ,"75031690":1,"8374675" ,"943310677":1},"o" ,"p":[],"q":1260321306,"r":1260492177},{"a":31,"b":1,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k" ,"l" ,"m" ,"n":[],"o" ,"p":[],"q":1260407625,"r":1260598769},{"a":34,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":30,"l":17,"m":17,"n":{"10177679" ,"16513950":1,"19783570":1,"20194034" ,"2175835":1,"25779663" ,"328410816" ,"3663649":1,"3783771":1,"41503729":1,"41892699":1,"43477953":1,"4469715" ,"532102" ,"538815525":1,"63322968":1,"649460555":1,"8374675":1},"o" ,"p":[],"q":1260201287,"r":1260490120},{"a":55,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":26,"l":15,"m":15,"n":{"16513950":1,"25779663" ,"3663649":1,"41503729":1,"41892699":1,"43477953":1,"4469715":1},"o" ,"p":[],"q":1260321278,"r":1260485140},{"a":31,"b":1,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k" ,"l" ,"m" ,"n":[],"o" ,"p":[],"q":1260407626,"r":1260595185},{"a":34,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":31,"l":18,"m":18,"n":{"10177679" ,"16513950":1,"19783570":1,"20194034":1,"2175835" ,"25779663":1,"328410816":1,"3663649":1,"3783771" ,"41503729":1,"41892699":1,"43477953" ,"4469715" ,"532102" ,"538815525" ,"63322968":1,"649460555":1,"8374675":1},"o" ,"p":[],"q":1260201287,"r":1260490120},{"a":55,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":25,"l":14,"m":14,"n":{"125462791" ,"13331147":1,"16513950":1,"2175835":1,"25779663" ,"328410816" ,"3663649":1,"3783771":1,"41503729":1,"41892699":1,"43477953" ,"4469715":1,"63322968":1,"649460555":1,"8374675" ,"943310677":1},"o" ,"p":[],"q":1260321277,"r":1260491057},{"a":31,"b":1,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k" ,"l" ,"m" ,"n":[],"o" ,"p":[],"q":1260407626,"r":1260595186},{"a":34,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":32,"l":19,"m":19,"n":{"10177679":1,"16513950":1,"19783570":1,"20194034":1,"25779663":1,"3663649":1,"3783771":1,"41503729":1,"41892699":1,"532102" ,"538815525":1,"649460555":1,"8374675":1},"o" ,"p":[],"q":1260201286,"r":1260483680},{"a":55,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":25,"l":14,"m":14,"n":{"16513950":1,"2175835":1,"25779663":1,"328410816":1,"3663649":1,"3783771" ,"41503729":1,"41892699":1,"43477953":1,"4469715":1,"63322968":1,"649460555" ,"8374675":1},"o" ,"p":[],"q":1260321276,"r":1260490120},{"a":33,"b":1,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k" ,"l" ,"m" ,"n":[],"o" ,"p":[],"q":1260407629,"r":1260595187},{"a":56,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j":2,"k":26,"l":15,"m":15,"n":{"10177679":1,"16513950":1,"260548988":1,"28364441":1,"361486206":1,"3783771":1,"41892699":1,"532102" ,"538815525":1,"649460555":1,"8374675":1},"o" ,"p":[],"q":1260346320,"r":1260461583},{"a":106,"b":6,"c" ,"d" ,"e":1,"f" ,"g" ,"h":1,"i":100,"j" ,"k":28,"l":16,"m":19,"n":{"110933010":1,"260548988":1,"3663649":1,"39206992":1,"41892699" ,"43477953":1,"63322968" ,"649460555" ,"75031690" },"o" ,"p":[],"q":1260407621,"r":1260600939}],"items":{"1":{"itemId":1},"2":{"itemId":98},"3":{"itemId":215},"4":{"itemId":100},"8":{"itemId":80003},"9":{"itemId":90001}},"user":{"healthMode":{"serverTime":1260601148,"set" ,"valid" },"pf":1}}
best regard!
robustwell
|
|
|
|
|
I am not sure what you are asking but -O , i.e. a capital letter O preceded by a minus sign which creates a smiley, is not a valid JSON object so cannot be parsed.
John
|
|
|
|
|
Thanks very much for making this useful library available.
I've found that JSON Spirit can't correctly handle the double numbers.
I have in JSON file:
{
"ground water volume flow rate" : 1234567890.123456789,
}
I read this value with:
...
jsonObj.at("ground water volume flow rate").get_real();
...
The number that I get is: 1.23457e+09
It looks like JSON Spirit handle the double numbers as float numbers (cuts till 6 decimal digits).
Is it possibe to get numbers as double?
Thanks, Tatjana
|
|
|
|
|
I don't get the same problem. Json Spirit has used doubles since verion 2.01 which was released about 2 years ago. It will read to 17 decimal places. The following code outputs:
1234567890.1234567
{"ground water volume flow rate":1234567890.123457}
mValue value;
read( "{\"ground water volume flow rate\" : 1234567890.123456789 }", value );
const mObject& o = value.get_obj();
const double d = o.find("ground water volume flow rate")->second.get_real();
const string s = write( o );
cout << setprecision( 18 ) << d << endl;
cout << s << endl;
John
|
|
|
|
|
Thanks John! It was my mistake. What I needed was setprecision(...), sorry I'm relatively new in C++.
Tatjana
|
|
|
|
|
Thanks very much for making this library available, I've found it extraordinarily useful.
I've found that JSON Spirit can't correctly handle multiple top-level objects in a stream unless they are separated by at least one character. I'm not sure if this is a limitation of JSON Spirit or Boost. Is this a known bug or requirement? Is there any easy way around it? I'm using the latest release of JSON Spirit (4.02) and Boost IOstreams 1.40.0.1.
Example program:
#include "json_spirit.h"
#include <sstream>
#include <string>
int main(int argc, char **argv) {
std::string s = argv[1];
std::istringstream str(s);
json_spirit::Value v;
bool succ = json_spirit::read(str, v);
assert(succ);
printf("Parsed: %s\n", json_spirit::write(v).c_str());
succ = json_spirit::read(str, v);
assert(succ);
printf("Parsed: %s\n", json_spirit::write(v).c_str());
}
Example output:
$ ./simple_test "{\"test\":1}{\"test\":2}"
Parsed: {"test":1}
Parsed: "test"
./simple_test "{\"test\":1} {\"test\":2}"
Parsed: {"test":1}
Parsed: {"test":2}
Only the second run parsed it correctly, presumably because there is a space between the two objects.
Any guidance would be much appreciated. Thanks!
Jeremy
|
|
|
|
|
Yes it definitely looks like a bug. Interestingly it only occurs when reading streams, reading multiple top level objects from a string works. I will look onto it.
John
|
|
|
|
|
Thanks John. I've been poking around and my working assumption is that it has something to do with multi-pass and looking ahead in the stream, but I haven't made much progress yet.
|
|
|
|
|
The problem does seem to be the multi_pass iterator. Basically, it buffers an extra character from the stream, and when the read_stream call returns, the multi_pass iterators get destroyed, and the character has permanently disappeared from the stream. Here's a simple patch that works for me, which just inserts the last character back into the stream:
<pre>
--- json_spirit_reader.cpp 2009-12-02 17:06:46.000000000 -0800
+++ json_spirit_reader.cpp.new 2009-12-02 17:06:28.000000000 -0800
@@ -621,7 +621,13 @@
{
Multi_pass_iters< Istream_type > mp_iters( is );
- return read_range( mp_iters.begin_, mp_iters.end_, value );
+ bool succ = read_range( mp_iters.begin_, mp_iters.end_, value );
+
+ if( mp_iters.begin_ != mp_iters.end_ ) {
+ is.putback(*(mp_iters.begin_));
+ }
+
+ return succ;
}
template< class Istream_type, class Value_type >
@@ -630,6 +636,11 @@
const Multi_pass_iters< Istream_type > mp_iters( is );
add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
+
+ if( mp_iters.begin_ != mp_iters.end_ ) {
+ is.putback(*(mp_iters.begin_));
+ }
+
}
}
</pre>
|
|
|
|
|
Thanks I appreciate you posting the patch. Unfortunately it doesn't work in all cases. Parsing "12 34 56" using the read or throw function results in a '1' being put back, the iterator must in this case be pointing one before the end of the object!
Interestingly multiple objects are parsed correctly if you create the multi_pass iterators then use them for the multiple parses, i.e. don't create and destroy the iterators on each parse.
I will continue looking for a complete fix. I assume your fix works for you if you are not using the read or throw functions. I have posted a question on the Spirit mailing list, http://sourceforge.net/mailarchive/forum.php?thread_name=190860.69208.qm%40web46015.mail.sp1.yahoo.com&forum_name=spirit-general
Regards
John
|
|
|
|
|
Thanks for the great library; it seems to have everything I need.
For your information, I am using boost 1.80, and everything works fine. (In case you want to update the opening paragraph). I have successfully compiled and linked it into a project (and I ran your test files, which came out successful.)
Edit: I'm using Visual Studio 2008, Express Edition.
|
|
|
|
|
Thanks for the info which I can confirm ( of course you mean 1.40 ). I am please you like the library.
Regards
John
|
|
|
|
|
>of course you mean 1.40
Yep, apologies for the typo. I also compiled it against 1.41.0, just for the sake of completeness. All is working smoothly.
My only question: when you check against types (.get_value()), why do you use assert() instead of throwing an exception on failure? It is difficult to react to asserts higher up in (my) code.
|
|
|
|
|
I suppose there is case for throwing an exception. For example if you were expecting data in a particular format you might not want to check a value's type before getting the value. It would be better just to receive an exception if the data was invalid. I have thought about parametrising the error reporting mechanism to allow users to specify that they want exceptions while maintaining backwards compatibility. Alternatively users could put a wrapper round the read functions throwing an exception if a value's type isn't the one expected.
John
|
|
|
|
|
The asserts aren't a big deal for me; I'll either re-write the relevant code or just re-define the assert macro. (Or wrap the read function, as you suggested. Hadn't thought of that earlier. )
In terms of library design, the decision is of course yours. Perhaps I am coming from too much of a Java mindset, where it's considered ok to just "try it and handle the general case of failure", but stopping the world is frowned upon. Actually, adding an exception-handling function as a parameter to the "read" function sounds pretty safe (that's what you mean when you said parametrising the error reporting mechanism, right?). The default exception-handling function could just be "assert(false)", which should preserve the current behavior.
Thanks again for the response. I'll work around the assert statement in my own way, but I'm looking forward to see how you implement a solution into the library's next release.
|
|
|
|
|
The following can be added to the CMakeLists.txt in order to add CPack packaging and a "make install" target.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f141931..f897f1c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,3 +3,20 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(json_spirit)
SUBDIRS(json_spirit json_demo json_map_demo json_test)
INCLUDE_DIRECTORIES(json_spirit)
+
+
+INSTALL(
+ FILES
+ ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit.h
+ ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_reader.h
+ ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_utils.h
+ ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_value.h
+ ${CMAKE_SOURCE_DIR}/json_spirit/json_spirit_writer.h
+ DESTINATION include)
+
+INSTALL(
+ FILES
+ ${CMAKE_BINARY_DIR}/json_spirit/libjson_spirit.a
+ DESTINATION lib)
+
+INCLUDE(CPack)
|
|
|
|
|
Thanks for the post. It is not clear to me what the rational for using CPack would be, i.e. what the use case is. It is the first time I have heard of CPack so please excuse my ignorance. Is the idea to produce an installer for precompiled object libraries and include files? If this is the case it sort of looks like overkill to me. Compiling the library is not difficult as the only dependency in boost. (There would also probably be some work to produce threaded and multi-threaded versions as Spirit needs to be linked to boost.thread to make it thread safe.)
Regards
John
|
|
|
|
|
Hi John,
Yes, the 'include(CPack)' line is just there to produce a precompiled tarball.
It only requires a small amount of work to be able to produce .deb or .rpm files, if you're willing to take the patches, I'll send them over to you. We plan to deploy the lib on several machines so having it packaged is a must.
OTOH, the 'INSTALL' directive is there to be able to issue 'make install' once you've compiled the binary.
On an unrelated note, it would be great to have the code located on some central repo, do you mind me setting up a git tree at github.com ?
Thanks,
Frederik Deweerdt
|
|
|
|
|
Hi Frederik,
I'd be happy to add a patch. I have been meaning get around to releasing a new version, just containing some minor fixes to allow it to be compiled with MSVC 2010, so I can incorporate the patch in the next release.
You are welcome to set up a git tree. I have been using subversion myself, I haven't used git. Probably about time I tried it out.
Regards
John
|
|
|
|
|
Hi John,
I've setup a git tree at github:
git clone git://github.com/deweerdt/JSON-Spirit.git
A soon as you get an account there, I'll add you on the admin list (or you can fork the tree for your own use).
Feel free to contact me by email it's surname.name at gmail.com.
Regards,
Frederik Deweerdt
|
|
|
|
|
Hi Frederik,
Thanks for that. I will add the CPack directives to the CMake file for the next release.
Regards
John
|
|
|
|
|
Hi,
It might be nice to show how easy it is to switch between using std::vector and std::map Value implementations in your demo.
Very nice code.
-- Mark
|
|
|
|
|