23 #include "pism/util/ConfigJSON.hh"
24 #include "pism/util/error_handling.hh"
25 #include "pism/util/pism_utilities.hh"
26 #include "pism/util/io/File.hh"
43 json_t *
object = root;
44 for (
auto object_name :
split(name,
'.')) {
46 object = json_object_get(
object, object_name.c_str());
60 json_t *array = json_array();
63 "failed to create an empty JSON array");
66 for (
const auto &v : data) {
67 json_t *value = json_pack(
"f", v);
70 "failed to pack a JSON number");
72 if (json_array_append_new(array, value) != 0) {
74 "failed to add an element to a JSON array");
85 const json_t *input) {
86 std::vector<double> result;
88 if (json_typeof(input) != JSON_ARRAY) {
90 "%s is not an array", name);
93 size_t N = json_array_size(input);
95 for (
size_t k = 0;
k < N; ++
k) {
96 json_t *value = json_array_get(input,
k);
99 "failed to get an element of %s",
104 if (json_unpack(value,
"F", &v) == 0) {
108 "failed to convert an element of %s to double",
117 template<
typename PISMType,
typename TMPType>
119 int type,
const char *fmt, std::map<std::string,PISMType> &accum) {
123 json_object_foreach(root, key, value) {
124 std::string parameter = path + key;
125 int value_type = json_typeof(value);
126 if (value_type == type) {
128 if (json_unpack(value, fmt, &tmp) == 0) {
129 accum[parameter] = tmp;
132 "failed to json_unpack %s using format %s",
133 parameter.c_str(), fmt);
135 }
else if (value_type == JSON_OBJECT) {
136 get_all_values<PISMType, TMPType>(value, parameter +
".", type, fmt, accum);
142 std::map<std::string, std::vector<double> > &accum) {
146 json_object_foreach(root, key, value) {
147 std::string parameter = path + key;
149 switch (json_typeof(value)) {
162 template<
typename PISMType,
typename TMPType>
163 static PISMType
get_value(json_t *
object,
const std::string &name,
164 const char *fmt,
const char *type_name) {
171 if (json_unpack(value, fmt, &tmp) == 0) {
175 "failed to convert %s to a %s", name.c_str(), type_name);
186 static void set_value(json_t *data,
const std::string &name, json_t *value) {
187 std::vector<std::string> path =
split(name,
'.');
188 if (path.size() == 0) {
193 std::string key = path.back();
196 json_t *
object = NULL;
203 if (
object != NULL) {
204 if (json_is_object(
object)) {
205 json_object_set_new(
object, key.c_str(), value);
208 name.c_str(),
join(path,
".").c_str());
212 name.c_str(),
join(path,
".").c_str());
237 m_data = json_load_file(
filename.c_str(), JSON_DECODE_INT_AS_REAL, &error);
241 " at line %d, column %d.",
242 filename.c_str(), error.line, error.column);
255 m_data = json_loads(
string.c_str(), JSON_DECODE_INT_AS_REAL, &error);
259 " at line %d, column %d.",
260 string.c_str(), error.line, error.column);
269 char *tmp = json_dumps(
m_data, JSON_INDENT(2) | JSON_ENSURE_ASCII | JSON_SORT_KEYS);
281 std::map<std::string, double> scalars;
282 get_all_values<double, double>(
m_data,
"", JSON_REAL,
"F", scalars);
284 for (
const auto &p : scalars) {
285 result[p.first] = {p.second};
295 get_all_values<std::string, const char*>(
m_data,
"", JSON_STRING,
"s", result);
301 get_all_values<bool, int>(
m_data,
"", JSON_TRUE,
"b", result);
302 get_all_values<bool, int>(
m_data,
"", JSON_FALSE,
"b", result);
311 const std::vector<double> &values) {
324 return get_value<double, double>(
m_data, name,
"F",
"number");
332 "%s was not found", name.c_str());
339 return get_value<std::string, const char *>(
m_data, name,
"s",
"string");
343 return get_value<bool, int>(
m_data, name,
"b",
"flag");
virtual Flags all_flags_impl() const
virtual std::string get_string_impl(const std::string &name) const
virtual std::vector< double > get_numbers_impl(const std::string &name) const
virtual double get_number_impl(const std::string &name) const
virtual Doubles all_doubles_impl() const
virtual void set_number_impl(const std::string &name, double value)
virtual void read_impl(const File &nc)
void init_from_file(const std::string &filename)
virtual void set_flag_impl(const std::string &name, bool value)
void init_from_string(const std::string &string)
virtual void set_string_impl(const std::string &name, const std::string &value)
virtual bool is_set_impl(const std::string &name) const
virtual void set_numbers_impl(const std::string &name, const std::vector< double > &values)
ConfigJSON(units::System::Ptr unit_system)
virtual void write_impl(const File &nc) const
virtual Strings all_strings_impl() const
virtual bool get_flag_impl(const std::string &name) const
std::map< std::string, std::string > Strings
std::map< std::string, std::vector< double > > Doubles
std::map< std::string, bool > Flags
std::string filename() const
Returns the name of the file used to initialize the database.
A class for storing and accessing PISM configuration flags and parameters.
void write_attribute(const std::string &var_name, const std::string &att_name, io::Type nctype, const std::vector< double > &values) const
Write a multiple-valued double attribute.
std::string read_text_attribute(const std::string &var_name, const std::string &att_name) const
Get a text attribute.
High-level PISM I/O class.
static RuntimeError formatted(const ErrorLocation &location, const char format[],...) __attribute__((format(printf
build a RuntimeError with a formatted message
std::shared_ptr< System > Ptr
#define PISM_ERROR_LOCATION
static void get_all_values(json_t *root, const std::string &path, int type, const char *fmt, std::map< std::string, PISMType > &accum)
static PISMType get_value(json_t *object, const std::string &name, const char *fmt, const char *type_name)
static json_t * pack_json_array(const std::vector< double > &data)
static void get_all_arrays(json_t *root, const std::string &path, std::map< std::string, std::vector< double > > &accum)
std::string join(const std::vector< std::string > &strings, const std::string &separator)
Concatenate strings, inserting separator between elements.
std::vector< double > unpack_json_array(const char *name, const json_t *input)
static json_t * find_json_value(json_t *root, const std::string &name)
static void set_value(json_t *data, const std::string &name, json_t *value)
std::vector< std::string > split(const std::string &input, char separator)
Transform a separator-separated list (a string) into a vector of strings.