|
|
Comments and Discussions
|
 |
 |
GCC issues a bunch of warnings related to unused paramters.
The following diff fixes them:
<h1>Index: 3rdparty/JsonSpirit/json_spirit_reader_template.h</h1>
--- 3rdparty/JsonSpirit/json_spirit_reader_template.h (Revision 8559)
+++ 3rdparty/JsonSpirit/json_spirit_reader_template.h (Arbeitskopie)
@@ -363,7 +363,7 @@
}
<pre>
template< typename Iter_type >
- void throw_error( Iter_type /i/, const std::string& reason )
+ void throw_error( Iter_type /* i */, const std::string& reason )
{
throw reason;
}
@@ -382,32 +382,32 @@
{
}
- static void throw_not_value( Iter_type begin, Iter_type /end/ )
- static void throw_not_value( Iter_type begin, Iter_type /* end */ )
{
throw_error( begin, "not a value" );
}
- static void throw_not_array( Iter_type begin, Iter_type /end/ )
- static void throw_not_array( Iter_type begin, Iter_type /* end */ )
{
throw_error( begin, "not an array" );
}
- static void throw_not_object( Iter_type begin, Iter_type /end/ )
- static void throw_not_object( Iter_type begin, Iter_type /* end */ )
{
throw_error( begin, "not an object" );
}
- static void throw_not_pair( Iter_type begin, Iter_type /end/ )
- static void throw_not_pair( Iter_type begin, Iter_type /* end */ )
{
throw_error( begin, "not a pair" );
}
- static void throw_not_colon( Iter_type begin, Iter_type /end/ )
- static void throw_not_colon( Iter_type begin, Iter_type /* end */ )
{
throw_error( begin, "no colon in pair" );
}
- static void throw_not_string( Iter_type begin, Iter_type /end/ )
- static void throw_not_string( Iter_type begin, Iter_type /* end */ )
{
throw_error( begin, "not a string" );
}
I hope the diff works.
Thanks for the good work.
Regards,
pizzard
|
|
|
|
|
 |
Message Removed
modified 26-Mar-15 13:23pm.
|
|
|
|
 |
In version V4.08 on Ubuntu 14.04LTS the included cmake instructions indicate that BOOST_INCLUDEDIR should be set to "the directory containing Boost's headers". This does not work - instead the directory needs to be set to the Boost root directory (or any directory one up from the directory containing the Boost headers). There is another environment variable called BOOST_ROOT which does not need to be set.
|
|
|
|
 |
Message Removed
modified 4-Feb-15 19:16pm.
|
|
|
|
 |
If I read json objects from file I don't know the content of, and it has the following format:
{
"name1": "fffff",
"blabla": false
"something_else" : 44.5
}
How do I get a list containing "name1", "blabla", "somthing_else" ?
|
|
|
|
 |
JSON Spirit objects are either an std::vector of name/values pairs or an std::map of names to values. To get a list of all the field names in an object you just iterate through the elements.
const string json_input = "{"
"\"name1\": \"fffff\","
"\"blabla\": false,"
"\"something_else\" : 44.5"
"}";
mValue value;
read( json_input, value );
const mObject& obj = value.get_obj();
for( mObject::const_iterator i = obj.begin(); i != obj.end(); ++i )
{
cout << i->first << endl;
}
Regards
John
|
|
|
|
 |
Nice, I wish it was in the tutorial. Or It'd be nice to have a method that does it. Because when you have little time to choose JSON library, you look through the methods that it provides to determine if it is easy to use the library and if you can achieve your goals with it by the most evident way. The code is well written, though, to my mind, the "rival" library is easier to understand.
Thank you for your help!
|
|
|
|
 |
I am getting these errors while trying to compile a program using json_spirit
json_spirit\json_spirit_reader.o: too many sections (40434)
json_spirit_reader.o: File too big
Is there a work around?
MingW 4.9.1
Windows 7 64-bit with 16 GB of memory
|
|
|
|
 |
There should be a linker option for this. I don't know what it is for MingW but for MSVC 2012 you need to link with "/bigobj". There is probably some similarly sounding name for MingW.
It might also be helpful to disable the Value types that you do not need. This is done by commenting out the defines below that you do not need in json_spirit_value.h
#define JSON_SPIRIT_VALUE_ENABLED
#define JSON_SPIRIT_WVALUE_ENABLED
#define JSON_SPIRIT_MVALUE_ENABLED
#define JSON_SPIRIT_WMVALUE_ENABLED
Regards
John
|
|
|
|
 |
I did not find the /bigobject switch in MinGW.
Also was already enabling only mValue ( #define JSON_SPIRIT_WVALUE_ENABLED ) when I ran into the error.
|
|
|
|
|
 |
I compiled my code using clang 3.4.2, and got warnings about needing an 'inline' keyword for 'value_type_to_string' in json_spirit_value.h
Here's a context diff for my fix:
diff --git a/json_spirit/json_spirit_value.h b/json_spirit/json_spirit_value.h
index 2f36cf4..9fb90ac 100644
--- a/json_spirit/json_spirit_value.h
+++ b/json_spirit/json_spirit_value.h
@@ -583,7 +583,7 @@ namespace json_spirit
return internal_::get_value( *this, internal_::Type_to_type< T >() );
}
- static std::string value_type_to_string( const Value_type vtype )
+ static inline std::string value_type_to_string( const Value_type vtype )
{
switch( vtype )
{
|
|
|
|
 |
Hi
I'm trying to use the library in a multithreaded application and I'm doing something wrong.
I've un-commented the threading #define and put this into the CMakeList file (I'm not familiar with CMake)
SET(JSON_SPIRIT_SRCS
json_spirit_reader.cpp json_spirit_reader.h json_spirit_value.cpp json_spirit_value.h
json_spirit_writer.cpp json_spirit_writer.h json_spirit.h json_spirit_error_position.h
json_spirit_reader_template.h json_spirit_stream_reader.h json_spirit_utils.h
json_spirit_writer_options.h json_spirit_writer_template.h )
FIND_PACKAGE(Boost COMPONENTS system thread REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ADD_LIBRARY(json_spirit STATIC ${JSON_SPIRIT_SRCS})
FIND_PACKAGE(Boost COMPONENTS thread system REQUIRED)
TARGET_LINK_LIBRARIES(json_spirit ${Boost_LIBRARIES})
FIND_PACKAGE(Threads REQUIRED)
TARGET_LINK_LIBRARIES(json_spirit ${CMAKE_THREAD_LIBS_INIT})
The library builds OK but the linker crashes in my project
g++ -L"/home/pads/workspace/WikiDBus/json_spirit_v4.08/build/json_spirit" -L/usr/lib/i386-linux-gnu/ -o "WikiDBus" ./src_server/MapContainer.o ./src_server/WikiDBus_s.o ./src_server/WikiServer.o ./src_server/jsonParser.o -ldbus-c++-1 -lboost_thread -lboost_system -ljson_spirit -lcurl
/home/pads/workspace/WikiDBus/json_spirit_v4.08/build/json_spirit/libjson_spirit.a(json_spirit_reader.cpp.o): In function `__static_initialization_and_destruction_0(int, int)json_spirit_reader.cpp:(.text+0x72d): undefined reference to `boost::system::generic_category()json_spirit_reader.cpp:(.text+0x737): undefined reference to `boost::system::generic_category()json_spirit_reader.cpp:(.text+0x741): undefined reference to `boost::system::system_category()
I've been googling trying to fix this but I'm pretty lost at the moment.
Thanks!
|
|
|
|
 |
Hi, I cannot see any errors in your CMake code. I wonder why you are linking to CMAKE_THREAD_LIBS_INIT, I haven't found that necessary myself. I also have not needed to link to boost.system although a google search suggests it is a fix to your link errors.
Below is my latest json_spirit/CMakeLists.txt file, part of a the next forthcoming version. I have added a CMake cached flag to enable multi-thread support. You could try this to see if it makes a difference.
# Copyright John W. Wilkinson 2007 - 2014
# Distributed under the MIT License, see accompanying file LICENSE.txt
# json spirit version 4.08
SET(JSON_SPIRIT_SRCS
json_spirit_reader.cpp json_spirit_reader.h
json_spirit_value.cpp json_spirit_value.h
json_spirit_writer.cpp json_spirit_writer.h
json_spirit.h
json_spirit_error_position.h
json_spirit_reader_template.h
json_spirit_stream_reader.h
json_spirit_utils.h
json_spirit_writer_options.h
json_spirit_writer_template.h )
IF( ${MSVC12} )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj" )
ENDIF()
SET( JSON_SPIRIT_MULTI_THREAD "OFF" CACHE BOOL "enabled multithread support" )
IF( ${JSON_SPIRIT_MULTI_THREAD} STREQUAL "ON" )
MESSAGE( "enabling multithread support" )
FIND_PACKAGE(Boost 1.34 REQUIRED COMPONENTS thread)
ELSE()
FIND_PACKAGE(Boost 1.34 REQUIRED)
ENDIF()
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ADD_LIBRARY(json_spirit STATIC ${JSON_SPIRIT_SRCS})
TARGET_LINK_LIBRARIES(json_spirit ${Boost_LIBRARIES})
Regards
John
|
|
|
|
 |
Hello and thank you for this helpful code and your support of it.
I have a partial implementation but am unable to figure out how to properly write nested structures such as the following:
{
"identifier": "id",
"label": "name",
"items": [
{
"id": "Vehicle_n",
"name": "Vehicle",
"type": "root",
"children": [
{
"_reference": "Passenger_n"
},
{
"_reference": "Commercial_n"
}
]
}
]
}
Can you give me a hint as to how I set up "items" so that its value is an array as shown?
Thanks!
|
|
|
|
 |
Hi Greg,
The following code does this.
Object root;
root.push_back( Pair( "identifier", "id" ) );
root.push_back( Pair( "label", "name" ) );
root.push_back( Pair( "items", Array() ) );
Array& items_array = root.back().value_.get_array();
items_array.push_back( Object() );
Object& item_1 = items_array.back().get_obj();
item_1.push_back( Pair( "id", "Vehicle_n" ) );
item_1.push_back( Pair( "name", "Vehicle" ) );
item_1.push_back( Pair( "type", "root" ) );
item_1.push_back( Pair( "children", Array() ) );
Array& children_array = item_1.back().value_.get_array();
children_array.push_back( Object() );
Object& child_1 = children_array.back().get_obj();
child_1.push_back( Pair( "_reference", "Passenger_n" ) );
children_array.push_back( Object() );
Object& child_2 = children_array.back().get_obj();
child_2.push_back( Pair( "_reference", "Commercial_n" ) );
cout << write_formatted( root ) << endl;
Regards
John
|
|
|
|
 |
John, thank you so much for taking the time to write such a great response. It seems so obvious now.
Greg
|
|
|
|
 |
Hello John,
I got trouble with finding the size of json object. In the sample codes you did it with returned array, How can I do that with mValue object, I looked into your codes but couldn't find any size method.
Regards
|
|
|
|
 |
A mObject is a std::map so calling its size function will return the number of name/value pairs in the object:
mValue val = ...; mObject obj = val.get_obj();
std::cout << obj.size() << endl;
Regards
John
|
|
|
|
 |
If I change line 224 in
json_test/json_spirit_reader_test.cpp
from
" \"name 1\" : \"value 1\",\n"
to
" \"name 1\" : \"va;lue 1\",\n"
the test no longer passes. It seems that semicolons inside strings are not parsed correctly.
|
|
|
|
 |
Sorry, I was not modifying the tests correctly. There is no bug.
|
|
|
|
 |
Hello Mr. Wilkinson,
Firstly I thank you for this great work. I want to read a recursive json data, where there is two part condition and action. Action part is going to be a string, but it will come in the json file as below. The condition part is representation of tree in json format. I am wondering is this possible to read this file with jsonspirit, and if yes how can I do that, could you please give me some hints?
Thank you
Best Regards
Oguz,
{
condition: {
root: "&",
leaves: [ "A",
{ root: "|",
leaves: ["p","r"]
}
]
}
action: ["a=7","event B"]
}
modified 4-Sep-14 12:14pm.
|
|
|
|
 |
Hi Oguz,
The file is not quite standard JSON, pair names such as condition have to be enclosed in quotes. JSON 5 doesn't have this requirement. You perhaps could use a JSON 5 parser to read your files if the file's format is beyond your control.
Regards
John
|
|
|
|
 |
Hi John,
The file format is actually in my control, so we can think the names (condition, root, leaves) as enclosed in quotes. How about in that situtation? Can we read recursive data?
Best Regards
Oguz
|
|
|
|
 |
Hi Oguz,
Yes, that would be fine, but I am not sure what you mean by "recursive" in this context?
Regards
John
|
|
|
|
 |
Sorry, that's my mistake. To be more clear this there can be number of "root" and "leaves" pair in this file and leaves can include many other "root" and "leaves" pair. The number is not definite. This condition part is actually the json resresentation of an tree (not necessarily binary tree). I am adding another sample to be more clear.
{
"condition": {
"root": "|",
"leaves": [
{ "root": ";",
"leaves": ["C", "K"]
}
,
{"root": "&",
"leaves": [
{ "root": "<",
"leaves": [ "a", "b"]
},
{"root": "=",
"leaves": ["f", "h"]
}
]
}
]
}
"action" : ["h=7", "event K"]
}
|
|
|
|
 |
Yes, JSON data forms a tree structure. Each node of the tree is a "value", see http://json.org/
|
|
|
|
 |
Thank you for your reply, my question is that; can I read json data which is in this format with your project. If yes, how can do that? I am actually asking that how should I use your code to handle this data?
Best Regards
Oguz
|
|
|
|
 |
Hi Oguz,
OK, the following code reads the data you provided originally. I made small changed to make it valid JSON. The key thing to remember is that each node in the tree is a JSON Value. After querying the value for its type, if you don't know this already, you can then retrieve its contents.
The JSON Spirit Code project article contains more information, although I assume you have read this already. I also recommend looking at the demo programs in the download.
Regards
John
const string str = "{\n"
" \"condition\": {\n"
" \"root\": \"&\",\n"
" \"leaves\": [ \"A\",\n"
" { \"root\": \"|\",\n"
" \"leaves\": [\"p\",\"r\"]\n"
" }\n"
" ]\n"
" },\n"
" \"action\": [\"a=7\",\"event B\"]\n"
"}";
mValue root;
const bool ok = read( str, root ); cout << value_type_to_string( root.type() ) << endl;
const mValue act = root.get_obj()["action"]; cout << value_type_to_string( act.type() ) << endl;
const mValue act_0 = act.get_array()[0]; const mValue act_1 = act.get_array()[1];
cout << value_type_to_string( act_0.type() ) << endl; cout << value_type_to_string( act_1.type() ) << endl;
cout << act_0.get_str() << endl; cout << act_1.get_str() << endl;
|
|
|
|
 |
Hi John,
Thanks for your reply. When I tried to use the code above, I get the following error.
" undefined reference to `json_spirit::read(std::string const&, json_spirit::Value_impl >&)'| "
I am using codeblocks IDE and I've done compile and linker setting both for "boost" and "jsonspirit/jsonspirit" library. I include the following headers according to your sample codes. I can't see any other configuration here but, the error is still on. Could you please help me with this?
"
#include "iostream"
#include "json_spirit.h"
#include "cassert"
#include "fstream"
#ifndef JSON_SPIRIT_MVALUE_ENABLED
#error Please define JSON_SPIRIT_MVALUE_ENABLED for the mValue type to be enabled
#endif
"
|
|
|
|
 |
Hi Oguz,
"undefined reference" is an error produced by the linker. The code has compiled correctly, you now need to link to the JSON Spirit library, file json_spirit.lib, as created by the library project in the download.
Regards
John
|
|
|
|
 |
I could not see any file as "json_spirit.lib" in the project I download. I only have a file named "json_spirit_lib" which is source browser database file under "\json_spirit_v4.08\Debug". I added that file and I am still getting the same error. Is there something wrong or do I need to create .lib file myself?
Kind Regards
Oguz
modified 7-Sep-14 5:39am.
|
|
|
|
 |
Hi Oguz,
The file you need will be called "json_spirit.lib", not "json_spirit_lib". Note, ".lib" denotes an object library. It will be created when you build the "json_spirit" project in the download, assuming no errors occurred during the build. As you have already got a ""\json_spirit_v4.08\Debug" folder I guess that you have already built it. I have never used codeblocks so I don't know where codeblocks will place it.
Regards
John
|
|
|
|
 |
Hi John,
I actually opened your solution with Visual Studio 2013, and build the build result is like below. There are 5 projects and I built "json_spirit_lib" project, the others are "json_demo", "json_headers_only_demo", "json_map_demo", "json_test". When I built it the result is shown below and the created library is "json_spirit_lib.lib" there is nothing else. I could not resolve that.
Best regards
1>------ Build started: Project: json_spirit_lib, Configuration: Debug Win32 ------
1> json_spirit_writer.cpp
1> json_spirit_reader.cpp
1> Generating Code...
1> json_spirit.vcxproj -> C:\Users\oguz\Downloads\json_spirit_v4.08\Debug\json_spirit_lib.lib
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
|
|
|
|
 |
Hi Oguz,
This is what I get, I used CMake to generate the Visual Studio 2013 solution, perhaps that explains the differences butI would expect are superficial:
1>------ Rebuild All started: Project: json_spirit, Configuration: Debug x64 ------
1> Building Custom Rule C:/svn/json/json_spirit/CMakeLists.txt
1> CMake does not need to re-run because C:\svn\json\json_spirit\CMakeFiles\generate.stamp is up-to-date.
1> json_spirit_reader.cpp
1> json_spirit_value.cpp
1> json_spirit_writer.cpp
1> Generating Code...
1>json_spirit_value.obj : warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library
1> json_spirit.vcxproj -> C:\svn\json\json_spirit\Debug\json_spirit.lib
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
I would expect your "json_spirit_lib.lib" to be the same as my "json_spirit.lib" so I don't know why you still get the "unresolved external" after you have added your file. How did you add it, under what setting?
Regards
John
|
|
|
|
 |
Hi John,
I am dealing with this problem for two days and I still could not figure out what is the problem. As in the article There are two ways to use the library
-Build and link in the JSON Spirit an object library.
-Just include the relevant header files, i.e., "header only" use.
I am wondering, headers only version will work for my requirements? If yes what needs to change in the following part of code?
Furthermore, I will a file which includes many trees, (i.e. many condition and action parts in one .json file) and I need to parse that file. Could you give me a hint about how to accomplish that. Do I need to create a struct to read that part?
Regards
Oguz
const string str = "{\n"
" \"condition\": {\n"
" \"root\": \"&\",\n"
" \"leaves\": [ \"A\",\n"
" { \"root\": \"|\",\n"
" \"leaves\": [\"p\",\"r\"]\n"
" }\n"
" ]\n"
" },\n"
" \"action\": [\"a=7\",\"event B\"]\n"
"}";
mValue root;
const bool ok = read( str, root ); // read root value
cout << value_type_to_string( root.type() ) << endl; // this is an Object
const mValue act = root.get_obj()["action"]; // read the root's "action" field"
cout << value_type_to_string( act.type() ) << endl; // this is a Array
const mValue act_0 = act.get_array()[0]; // read both items in the array
const mValue act_1 = act.get_array()[1];
cout << value_type_to_string( act_0.type() ) << endl; // these are strings
cout << value_type_to_string( act_1.type() ) << endl;
cout << act_0.get_str() << endl; // retrieve the strings
cout << act_1.get_str() << endl;
modified 11-Sep-14 3:36am.
|
|
|
|
 |
Hi Oguz,
The only change you need to make is to include json_spirit_reader_template.h and json_spirit_writer_template.h instead of json_spirit.h. Then you will not need to link to the object library. Have you looked at the supplied headers only demo program? The downside is longer compile times for your code, which you can reduce by using pre-compiled headers.
JSON Spirit will read a whole JSON tree no matter how many branches or depth, with the limitation of the available memory. How you subsequently handle the data is up to you, the design choice here would depend on the application needs. I would suggest you give it a go, keeping things as simple as possible, putting features in only when you need them.
Regards
John
|
|
|
|
 |
Hi John,
Thnx for the help, I still get the error and dont see any reason, I make it work with read_string method but read (str, root) gives undefined reference error with headers only version and read_stream method returns null object. Have any idea?
I am also wondering what is the difference between value and mvalue? Read_string is not working with Value enabled but works when mValue is enabled.
Regards
Oguz
modified 14-Sep-14 10:25am.
|
|
|
|
 |
Hi Oguz,
I am afraid I cannot tell what the issue is. Have you got the header only demo program to build and run correctly. You could then use this as a base for your program.
Regards
John
PS. If you are new to programming you will probably find C++ has a large leaning curve. Using a language like Python would be easier to learn. I would use Python myself for small projects that are not CPU intensive.
|
|
|
|
 |
Hi John,
Thnx for the advice, I am kind of new but C++ is a requirement for my task, so I keep on with c++.
Could you please tell me how can I reach data in condition part. This part of code, writes null to the screen, but I am able to get action part in my code.
---Below code returns null
read_stream( is, root );
const mValue cndt = root.get_obj()["root"];
cout << value_type_to_string( cndt.type() ) << endl; //This one gives null
---This one returns array and I can get elemants of array.
const mValue act = root.get_obj()["action"]; // read the root's "action" field"
cout << value_type_to_string( act.type() ) << endl; // this returns an Array
|
|
|
|
 |
Hi Orgz, I don't know why you get a null in the first part of the code. Perhaps the read failed because the input was not valid JSON.
To get the array elements you first need to get the array inside the value object:
mArray arr = act.get_array();
Each item of the array are also values:
mValue item_1 = arr[0];
You can then find what type this array value is and then process it accordingly, e.g.
if( item_1.type() == str_type )
{
string s = item_1.get_str();
...
}
Regards
John
|
|
|
|
 |
Hi John,
To get the object in the object I've tried this but this one gives an error. My json file is in the bottom part.
const mValue cndt = root.get_obj()["condition"];
cout << value_type_to_string( cndt.type() ) << endl; // this returns Object
const mValue cndt1 = cndt.get_obj()["root"];
cout << value_type_to_string( cndt1.type() ) << endl; // this gives error which I added below.
How can I go deeper in the condition part, e.g. to read root and leaves values?
Best Regards
{
"condition": {
"root": "&",
"leaves": [ "A",
{ "root": "|",
"leaves": ["p","r"]
}
]
},
"action": ["a=7","event B"]
}
Error: D:\CodeBlocksWorkspace\PrjThss\main.cpp|46|error: passing 'const Object {aka const std::map,
json_spirit::Value_impl > >, std::less >,
std::allocator, json_spirit::Value_impl > > > > >}'
as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string; _Tp|
|
|
|
|
 |
Hi Oguz,
The compiler error is because the std::map operator[] is non-const, see http://stackoverflow.com/questions/1474894/why-isnt-the-operator-const-for-stl-maps[^]
To fix it either use map::find instead of [] or perhaps more simply make the mValue objects non-const:
mValue root;
read_string( str, root );
mValue cndt = root.get_obj()["condition"];
cout << value_type_to_string( cndt.type() ) << endl;
mValue cndt1 = cndt.get_obj()["root"];
cout << value_type_to_string( cndt1.type() ); << endl
Regards
John
|
|
|
|
 |
Fantastic library. My one request would be a version macro, in the vein of the BOOST_VERSION macro. It's a handy thing to include in a compiled binary, so that months later, one can determine easily and with confidence which version of the library it was compiled against.
|
|
|
|
 |
Sound a good idea. I'll add a JSON_SPIRIT_VERSION macro to the next release.
Regards
John
|
|
|
|
 |
I needed to parse json5, so I modified your excellent library to do that. I put the result up on Google code. I do not know if you are interested in any of the changes that I have made. I am more than willing to merge it into JSON Spirit proper if you like.
Thanks
|
|
|
|
 |
I thank for the post. I won't add json5 support for now but I'll keep an eye on the progress of the proposal.
Regards
John
|
|
|
|
 |
Hey John,
We're using your library in production and added/hacked in support for long doubles. We weren't sure if anyone else would directly benefit from this but I thought it would be a good idea to post the code here and ask for feedback and gauge interest for the possibility of any part making it upstream. As background, we're running some code which regularly reaches 14+ digits of precision so we needed more bytes to store our data. We could have used a BigInt library like some probably have done but we found it best to modify the library directly.
Our hope is this can help others who have the same problem!
rough summary of patch:
-git a/src/json/json_spirit_reader_template.h b/src/json/json_spirit_reader_template.h
index 46f5892..e96b41a 100644
--- a/src/json/json_spirit_reader_template.h
+++ b/src/json/json_spirit_reader_template.h
@@ -31,11 +31,16 @@
#define spirit_namespace boost::spirit
#endif
namespace json_spirit
{
const spirit_namespace::int_parser < int64_t > int64_p = spirit_namespace::int_parser < int64_t >();
const spirit_namespace::uint_parser< uint64_t > uint64_p = spirit_namespace::uint_parser< uint64_t >();
+ const spirit_namespace::real_parser< long double, spirit_namespace::strict_real_parser_policies<long double> > ldouble = spirit_namespace::real_parser< long double, spirit_namespace::strict_real_parser_policies<long double> >();
+
template< class Iter_type >
bool is_eq( Iter_type first, Iter_type last, const char* c_str )
{
@@ -272,19 +277,27 @@ namespace json_spirit
+ void new_ldouble( long double ld )
+ {
+ add_to_current( ld );
+ }
private:
Semantic_actions& operator=( const Semantic_actions& );
@@ -425,6 +438,7 @@ namespace json_spirit
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( long double ) > Ldouble_action;
typedef boost::function< void( int64_t ) > Int_action;
typedef boost::function< void( uint64_t ) > Uint64_action;
@@ -438,6 +452,7 @@ namespace json_spirit
Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) );
Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) );
Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) );
+ Ldouble_action new_ldouble ( boost::bind( &Semantic_actions_t::new_ldouble, &self.actions_, _1 ) );
Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) );
Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) );
@@ -496,7 +511,8 @@ namespace json_spirit
;
number_
- = strict_real_p[ new_real ]
+ ldouble [ new_ldouble ]
| int64_p [ new_int ]
| uint64_p [ new_uint64 ]
;
diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h
index 13cc892..2fade72 100644
--- a/src/json/json_spirit_value.h
+++ b/src/json/json_spirit_value.h
@@ -23,8 +24,8 @@
namespace json_spirit
{
- enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
- static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
+ enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, ldouble_type, null_type };
+ static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "ldouble", "null"};
template< class Config > @@ -47,7 +48,9 @@ namespace json_spirit
Value_impl( int value );
Value_impl( int64_t value );
Value_impl( uint64_t value );
+
Value_impl( double value );
+ Value_impl( long double value );
Value_impl( const Value_impl& other );
@@ -67,7 +70,9 @@ namespace json_spirit
int get_int() const;
int64_t get_int64() const;
uint64_t get_uint64() const;
+
double get_real() const;
+ long double get_ldouble() const;
Object& get_obj();
Array& get_array();
@@ -83,7 +88,7 @@ namespace json_spirit
typedef boost::variant< String_type,
boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
- bool, int64_t, double > Variant;
+ bool, int64_t, double, long double > Variant;
Value_type type_;
Variant v_;
@@ -288,6 +293,14 @@ namespace json_spirit
}
template< class Config >
+ Value_impl< Config >::Value_impl( long double value )
+ : type_( ldouble_type )
+ , v_( static_cast< long double>( value ) )
+ , is_uint64_( false )
+ {
+ }
+
+ template< class Config >
Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
: type_( other.type() )
, v_( other.v_ )
@@ -420,6 +433,21 @@ namespace json_spirit
}
template< class Config >
+ long double Value_impl< Config >::get_ldouble() const
+ {
+ if( type() == int_type )
+ {
+ return is_uint64() ? static_cast< long double >( get_uint64() )
+ : static_cast< long double >( get_int64() );
+ }
+
+ check_type( ldouble_type );
+
+ return boost::get< long double >( v_ );
+ }
+
+
+ template< class Config >
@@ -420,6 +433,21 @@ namespace json_spirit
}
+ long double get_value( const Value& value, Type_to_type< long double > )
+ {
+ return value.get_ldouble();
+ }
+
+ template< class Value >
typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
{
diff --git a/src/json/json_spirit_writer_template.h b/src/json/json_spirit_writer_template.h
index 6b4978a..5385998 100644
--- a/src/json/json_spirit_writer_template.h
+++ b/src/json/json_spirit_writer_template.h
@@ -130,6 +130,9 @@ namespace json_spirit
case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8)
<< value.get_real(); break;
+ case ldouble_type: os_ << std::showpoint << std::fixed << std::setprecision(8)
+ << value.get_ldouble(); break;
+
case null_type: os_ << "null"; break;
default: assert( false );
}
Faiz (email faiz at mastercoin dot org )
|
|
|
|
 |
Thanks for the patch. I'll look to incorporating it into the next release.
Regards
John
|
|
|
|
|
 |
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
| First Posted | 15 Aug 2007 |
| Views | 2,189,704 |
| Downloads | 16,047 |
| Bookmarked | 269 times |
|
|