Compilation and use of cppcms
Please refer to my related articles.
Converts a C ++ object to a JSON string.
Assume there is a class response, two fields, one is status, 0 indicates correct. Others indicate errors. The other is the message field, indicating the specific information of the operation result. The Code is as follows:
class response {public: //0 is ok //other values are wrong int status; string message;};
Now you need to convert the data of the response object to a JSON string. You also need to write a template class. The Code is as follows:
namespace cppcms { namespace json { template<> struct traits<response> { static void set(value &v, response const& in) { v.set("status", in.status); v.set("message", in.message); } }; }}
Now, write the call code and view the running result.
#include <cppcms/json.h>...int main(int argc, char** argv) { response r1; r1.status=0; r1.message="ok"; cout<< cppcms::json::value(r1)<<endl; response r2; r2.status=1; r2.message="unknown error"; cout<< cppcms::json::value(r2)<<endl; return 0;}
Running result:
{"Message": "OK", "status": 0}
{"Message": "Unknown error", "status": 1}
Cppcms: JSON: Value code analysis
The reason why it is easy to convert to a JSON string is that the value class is used. Now let's analyze how the above call code works.
1. cppcms: JSON: Value (R1) creates an anonymous object value. The value constructor internally calls the set_value method. The V parameter is the response object.
template<typename T> value(T const &v) { set_value(v); }
2. The set_value method calls traits <t>: Set (this, V). This is the template method that we previously overloaded.
template<typename T> void set_value(T const &v) { traits<T>::set(this,v); }
3. The purpose of the rest is clear. The attribute of the value object must be stored in map in the form of key and value. Finally, it is converted to a JSON string and then output to the stream. Artyom reloads operator <function. The underlying implementation function is as follows:
std::ostream &operator<<(std::ostream &out,value const &v) { v.save(out); return out; } void value::save(std::ostream &out,int how) const { int tabs=(how & readable) ? 0 : -1; write(out,tabs); } void value::write(std::ostream &out,int tabs) const { std::locale original(out.getloc()); out.imbue(std::locale("C")); try { write_value(out,tabs); } catch(...) { out.imbue(original); throw; } out.imbue(original); } void value::write_value(std::ostream &out,int tabs) const { switch(type()) { case json::is_undefined: throw bad_value_cast("Can't write undefined value to stream"); case json::is_null: out<<"null"; break; case json::is_number: out<<std::setprecision(std::numeric_limits<double>::digits10+1)<<number(); break; case json::is_string: out<<escape(str()); break; case json::is_boolean: out<< (boolean() ? "true" : "false") ; break; case json::is_array: { json::array const &a=array(); unsigned i; indent(out,'[',tabs); for(i=0;i<a.size();) { a[i].write_value(out,tabs); i++; if(i<a.size()) indent(out,',',tabs); } indent(out,']',tabs); } break; case json::is_object: { json::object const &obj=object(); object::const_iterator p,end; p=obj.begin(); end=obj.end(); indent(out,'{',tabs); while(p!=end) { out<<escape(p->first); indent(out,':',tabs); p->second.write_value(out,tabs); ++p; if(p!=end) indent(out,',',tabs); } indent(out,'}',tabs); } break; default: throw bad_value_cast("Unknown type found: internal error"); } }
The above code contains a lot of details, many of which can be written and described independently. Here we mainly want to understand the internal design principles of cppcms: JSON: Value for better use. We will track it here for now.
Converts a JSON string to a C ++ object.
The following code demonstrates how to put the JSON string in the stream into the value object, and then find it using the get method. "null" is the default value when it cannot be found.
stringstream stream; stream << "{\"message\":\"ok\",\"status\":0}"; cppcms::json::value value2; stream >> value2; string m = value2.get("message","null");
You can also use a more rigorous get Method for reload. There is no default value. If it cannot be found, a bad_cast exception will be thrown.
/// /// Get an object of type T from the path \a path. Throws bad_value_cast if such path does not /// exists of conversion can't be done /// template<typename T> T get(std::string const &path) const { return at(path).get_value<T>(); }
I don't like to write a large article. This article mainly describes how to use it. By the way, I dug up the source code. The source code of cppcms will be further explored later.