1 #ifndef STAN__IO__JSON__JSON_DATA_HANDLER_HPP
2 #define STAN__IO__JSON__JSON_DATA_HANDLER_HPP
11 #include <boost/throw_exception.hpp>
12 #include <boost/lexical_cast.hpp>
26 std::pair<std::vector<double>,
27 std::vector<size_t> > >
32 std::pair<std::vector<int>,
33 std::vector<size_t> > >
59 std::vector<double> values_r_;
60 std::vector<int> values_i_;
61 std::vector<size_t> dims_;
62 std::vector<size_t> dims_verify_;
63 std::vector<bool> dims_unknown_;
74 dims_unknown_.clear();
81 return (key_.size() == 0
82 && values_r_.size() == 0
83 && values_i_.size() == 0
85 && dims_verify_.size() == 0
86 && dims_unknown_.size() == 0
104 key_(), values_r_(), values_i_(),
105 dims_(), dims_verify_(), dims_unknown_(),
106 dim_idx_(), dim_last_(), is_int_() {
120 if (0 == key_.size()) {
121 throw json_error(
"expecting JSON object, found array");
123 if (dim_idx_ > 0 && dim_last_ == dim_idx_) {
124 std::stringstream errorMsg;
125 errorMsg <<
"variable: " << key_ <<
", error: non-scalar array value";
130 if (dims_.size() < dim_idx_) {
132 dims_unknown_.push_back(
true);
133 dims_verify_.push_back(0);
135 dims_verify_[dim_idx_-1] = 0;
140 if (dims_[dim_idx_-1] == 0) {
141 std::stringstream errorMsg;
142 errorMsg <<
"variable: " << key_ <<
", error: empty array not allowed";
145 if (dims_unknown_[dim_idx_-1] ==
true) {
146 dims_unknown_[dim_idx_-1] =
false;
147 }
else if (dims_verify_[dim_idx_-1] != dims_[dim_idx_-1]) {
148 std::stringstream errorMsg;
149 errorMsg <<
"variable: " << key_ <<
", error: non-rectangular array";
153 && ((is_int_ && values_i_.size() > 0) || (values_r_.size() > 0)))
154 dim_last_ = dim_idx_;
160 std::stringstream errorMsg;
161 errorMsg <<
"variable: " << key_ <<
", error: nested objects not allowed";
172 std::stringstream errorMsg;
173 errorMsg <<
"variable: " << key_ <<
", error: null values not allowed";
178 std::stringstream errorMsg;
179 errorMsg <<
"variable: " << key_ <<
", error: boolean values not allowed";
185 if (0 == s.compare(
"-inf")) {
186 tmp = -std::numeric_limits<double>::infinity();
187 }
else if (0 == s.compare(
"inf")) {
188 tmp = std::numeric_limits<double>::infinity();
190 std::stringstream errorMsg;
191 errorMsg <<
"variable: " << key_ <<
", error: string values not allowed";
195 for (std::vector<int>::iterator it = values_i_.begin(); it != values_i_.end(); ++it)
196 values_r_.push_back(*it);
199 values_r_.push_back(tmp);
212 for (std::vector<int>::iterator it = values_i_.begin();
213 it != values_i_.end(); ++it)
214 values_r_.push_back(*it);
217 values_r_.push_back(x);
224 values_i_.push_back(n);
226 values_r_.push_back(n);
234 values_i_.push_back(n);
236 values_r_.push_back(n);
242 if (0 == key_.size())
return;
245 if (vars_r_.find(key_) != vars_r_.end()
246 || vars_i_.find(key_) != vars_i_.end()) {
247 std::stringstream errorMsg;
248 errorMsg <<
"attempt to redefine variable: " << key_;
254 std::pair<std::vector<int>,
255 std::vector<size_t> > pair;
256 if (dims_.size() > 1) {
257 std::vector<int> cm_values_i(values_i_.size());
259 pair = make_pair(cm_values_i, dims_);
262 pair = make_pair(values_i_, dims_);
264 vars_i_[key_] = pair;
266 std::pair<std::vector<double>,
267 std::vector<size_t> > pair;
268 if (dims_.size() > 1) {
269 std::vector<double> cm_values_r(values_r_.size());
271 pair = make_pair(cm_values_r, dims_);
273 pair = make_pair(values_r_, dims_);
275 vars_r_[key_] = pair;
281 if (dims_unknown_[dim_idx_-1])
284 dims_verify_[dim_idx_-1]++;
288 template <
typename T>
289 void to_column_major(std::vector<T>& cm_vals,
const std::vector<T>& rm_vals,
const std::vector<size_t>&
dims) {
290 for (
size_t i = 0; i< rm_vals.size(); i++) {
292 cm_vals[idx] = rm_vals[i];
297 if (dim_last_ > 0 && dim_idx_ < dim_last_) {
298 std::stringstream errorMsg;
299 errorMsg <<
"variable: " << key_ <<
", error: non-rectangular array";
302 dim_last_ = dim_idx_;
307 size_t rtl_dsize = 1;
308 for (
size_t i = 1; i < dims.size(); i++)
309 rtl_dsize *= dims[i];
312 if (rtl_offset >= rtl_dsize*dims[0]) {
313 std::stringstream errorMsg;
314 errorMsg <<
"variable: " << key_ <<
", unexpected error";
321 size_t rem = rtl_offset;
322 size_t ltr_offset = 0;
323 size_t ltr_dsize = 1;
324 for (
size_t i = 0; i < dims.size()-1; i++) {
325 size_t idx = rem / rtl_dsize;
326 ltr_offset += idx * ltr_dsize;
327 rem = rem - idx * rtl_dsize;
328 rtl_dsize = rtl_dsize / dims[i+1];
329 ltr_dsize *= dims[i];
331 ltr_offset += rem * ltr_dsize;
void end_object()
Handle the end of an object.
void start_object()
Handle the start of an object.
Abstract base class for JSON handlers.
void key(const std::string &key)
Handle the specified object key.
A json_data_handler is an implementation of a json_handler that restricts the allowed JSON text a set...
void start_text()
Handle the the start of the text.
void null()
Handle the null literal value.
void dims(const T &x, std::vector< int > &result)
void string(const std::string &s)
Handle the specified string value.
void boolean(bool p)
Handle the boolean literal value of the specified polarity.
void save_current_key_value_pair()
void end_text()
Handle the the end of the text.
void to_column_major(std::vector< T > &cm_vals, const std::vector< T > &rm_vals, const std::vector< size_t > &dims)
size_t convert_offset_rtl_2_ltr(size_t rtl_offset, const std::vector< size_t > &dims)
void end_array()
Handle the end of an array.
Exception type for JSON errors.
void number_double(double x)
Handle a the specified double-precision floating point value.
json_data_handler(vars_map_r &vars_r, vars_map_i &vars_i)
Construct a json_data_handler object.
void start_array()
Handle the start of an array.
void number_long(long n)
Handle a the specified long integer value.
void number_unsigned_long(unsigned long n)
Handle a the specified unsigned long integer value.