boost::any configuration_parser::convert_json(const json& _json) { switch (_json.type()) { case json::value_t::string: return _json.get<std::string>(); case json::value_t::number_float: return _json.get<double>(); case json::value_t::number_integer: case json::value_t::number_unsigned: return _json.get<int>(); case json::value_t::boolean: return _json.get<bool>(); case json::value_t::array: { std::vector<boost::any> array; for (auto&& jj : _json) { array.push_back(convert_json(jj)); } return array; } case json::value_t::object: { std::unordered_map<std::string, boost::any> object; //for (auto&& [k, v] : j.items()) { // Supported in later versions :( for (auto it = std::begin(_json); it != std::end(_json); ++it) { object.insert({it.key(), convert_json(it.value())}); } return object; } case json::value_t::null: return std::string{"NULL"}; default: const auto type = static_cast<std::uint8_t>(_json.type()); THROW(-1, (boost::format("unhandled type in json_typeof: %d") % type)); } } // parse_json_object
error configuration_parser::load_json_object(const std::string& _file) { json config; { std::ifstream in{_file}; if (!in) { std::string msg{"failed to open file ["}; msg += _file; msg += ']'; return ERROR( -1, msg ); } try { in >> config; } catch (const json::parse_error& e) { return ERROR(-1, boost::format("failed to parse json [file=%s, error=%s].") % _file % e.what()); } } irods::error ret = SUCCESS(); try { if ( root_.empty() ) { root_ = boost::any_cast<std::unordered_map<std::string, boost::any>>(convert_json(config)); } else { const auto json_object_any = convert_json(config); const auto& json_object = boost::any_cast<const std::unordered_map<std::string, boost::any>&>(json_object_any); for ( auto it = json_object.cbegin(); it != json_object.cend(); ++it ) { root_[it->first] = it->second; } } } catch ( const irods::exception& e ) { ret = irods::error(e); } catch ( const boost::bad_any_cast& ) { ret = ERROR(INVALID_ANY_CAST, "configuration file did not contain a json object."); } return ret; } // load_json_object
boost::any configuration_parser::convert_json(json_t* _val) { switch( json_typeof( _val )) { case JSON_INTEGER: return boost::any((int)json_integer_value(_val)); case JSON_STRING: return boost::any(std::string(json_string_value(_val))); case JSON_REAL: return boost::any(json_real_value(_val)); case JSON_TRUE: return boost::any(json_true()); case JSON_FALSE: return boost::any(json_false()); case JSON_NULL: return boost::any(std::string("NULL")); case JSON_ARRAY: { std::vector<boost::any> vector; size_t idx = 0; json_t* element = NULL; json_array_foreach(_val, idx, element) { try { vector.push_back(convert_json(element)); } catch (const irods::exception& e) { irods::log(e); } } return boost::any(vector); } case JSON_OBJECT: { std::unordered_map<std::string, boost::any> map; const char* key = NULL; json_t* subval = NULL; json_object_foreach( _val, key, subval ) { try { map.insert(std::pair<std::string, boost::any>(std::string(key), convert_json(subval))); } catch (const irods::exception& e) { irods::log(e); } } return boost::any(map); } } THROW( -1, (boost::format("unhandled type in json_typeof: %d") % json_typeof(_val) ).str()); } // parse_json_object
error configuration_parser::load_json_object( const std::string& _file ) { json_error_t error; json_t *json = json_load_file( _file.c_str(), 0, &error ); if ( !json ) { std::string msg( "failed to load file [" ); msg += _file; msg += "] json error ["; msg += error.text; msg += "]"; return ERROR( -1, msg ); } irods::error ret = SUCCESS(); try { if ( root_.empty() ) { root_ = boost::any_cast<std::unordered_map<std::string, boost::any> >(convert_json(json)); } else { const auto json_object_any = convert_json(json); const auto& json_object = boost::any_cast<const std::unordered_map<std::string, boost::any>&>(json_object_any); for ( auto it = json_object.cbegin(); it != json_object.cend(); ++it ) { root_[it->first] = it->second; } } } catch ( const irods::exception& e ) { ret = irods::error(e); } catch ( const boost::bad_any_cast& ) { ret = ERROR(INVALID_ANY_CAST, "configuration file did not contain a json object."); } json_decref( json ); return ret; } // load_json_object