1 #ifndef STAN_IO_JSON_JSON_DATA_HANDLER_HPP
2 #define STAN_IO_JSON_JSON_DATA_HANDLER_HPP
4 #include <boost/throw_exception.hpp>
5 #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> > >
58 std::vector<double> values_r_;
59 std::vector<int> values_i_;
60 std::vector<size_t> dims_;
61 std::vector<size_t> dims_verify_;
62 std::vector<bool> dims_unknown_;
73 dims_unknown_.clear();
80 return (key_.size() == 0
81 && values_r_.size() == 0
82 && values_i_.size() == 0
84 && dims_verify_.size() == 0
85 && dims_unknown_.size() == 0
103 key_(), values_r_(), values_i_(),
104 dims_(), dims_verify_(), dims_unknown_(),
105 dim_idx_(), dim_last_(), is_int_() {
119 if (0 == key_.size()) {
120 throw json_error(
"expecting JSON object, found array");
122 if (dim_idx_ > 0 && dim_last_ == dim_idx_) {
123 std::stringstream errorMsg;
124 errorMsg <<
"variable: " << key_
125 <<
", 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_
143 <<
", error: empty array not allowed";
146 if (dims_unknown_[dim_idx_-1] ==
true) {
147 dims_unknown_[dim_idx_-1] =
false;
148 }
else if (dims_verify_[dim_idx_-1] != dims_[dim_idx_-1]) {
149 std::stringstream errorMsg;
150 errorMsg <<
"variable: " << key_ <<
", error: non-rectangular array";
154 && ((is_int_ && values_i_.size() > 0) || (values_r_.size() > 0)))
155 dim_last_ = dim_idx_;
161 std::stringstream errorMsg;
162 errorMsg <<
"variable: " << key_
163 <<
", error: nested objects not allowed";
174 std::stringstream errorMsg;
175 errorMsg <<
"variable: " << key_ <<
", error: null values not allowed";
180 std::stringstream errorMsg;
181 errorMsg <<
"variable: " << key_
182 <<
", error: boolean values not allowed";
188 if (0 == s.compare(
"-inf")) {
189 tmp = -std::numeric_limits<double>::infinity();
190 }
else if (0 == s.compare(
"inf")) {
191 tmp = std::numeric_limits<double>::infinity();
193 std::stringstream errorMsg;
194 errorMsg <<
"variable: " << key_
195 <<
", error: string values not allowed";
199 for (std::vector<int>::iterator it = values_i_.begin();
200 it != values_i_.end(); ++it)
201 values_r_.push_back(*it);
204 values_r_.push_back(tmp);
217 for (std::vector<int>::iterator it = values_i_.begin();
218 it != values_i_.end(); ++it)
219 values_r_.push_back(*it);
222 values_r_.push_back(x);
230 values_i_.push_back(n);
232 values_r_.push_back(n);
241 values_i_.push_back(n);
243 values_r_.push_back(n);
249 if (0 == key_.size())
return;
252 if (vars_r_.find(key_) != vars_r_.end()
253 || vars_i_.find(key_) != vars_i_.end()) {
254 std::stringstream errorMsg;
255 errorMsg <<
"attempt to redefine variable: " << key_;
261 std::pair<std::vector<int>,
262 std::vector<size_t> > pair;
263 if (dims_.size() > 1) {
264 std::vector<int> cm_values_i(values_i_.size());
266 pair = make_pair(cm_values_i, dims_);
269 pair = make_pair(values_i_, dims_);
271 vars_i_[key_] = pair;
273 std::pair<std::vector<double>,
274 std::vector<size_t> > pair;
275 if (dims_.size() > 1) {
276 std::vector<double> cm_values_r(values_r_.size());
278 pair = make_pair(cm_values_r, dims_);
280 pair = make_pair(values_r_, dims_);
282 vars_r_[key_] = pair;
288 if (dims_unknown_[dim_idx_-1])
291 dims_verify_[dim_idx_-1]++;
295 template <
typename T>
297 const std::vector<T>& rm_vals,
298 const std::vector<size_t>& dims) {
299 for (
size_t i = 0; i< rm_vals.size(); i++) {
301 cm_vals[idx] = rm_vals[i];
306 if (dim_last_ > 0 && dim_idx_ < dim_last_) {
307 std::stringstream errorMsg;
308 errorMsg <<
"variable: " << key_ <<
", error: non-rectangular array";
311 dim_last_ = dim_idx_;
316 const std::vector<size_t>& dims) {
317 size_t rtl_dsize = 1;
318 for (
size_t i = 1; i < dims.size(); i++)
319 rtl_dsize *= dims[i];
322 if (rtl_offset >= rtl_dsize*dims[0]) {
323 std::stringstream errorMsg;
324 errorMsg <<
"variable: " << key_ <<
", unexpected error";
331 size_t rem = rtl_offset;
332 size_t ltr_offset = 0;
333 size_t ltr_dsize = 1;
334 for (
size_t i = 0; i < dims.size()-1; i++) {
335 size_t idx = rem / rtl_dsize;
336 ltr_offset += idx * ltr_dsize;
337 rem = rem - idx * rtl_dsize;
338 rtl_dsize = rtl_dsize / dims[i+1];
339 ltr_dsize *= dims[i];
341 ltr_offset += rem * ltr_dsize;
void end_object()
Handle the end of an object.
void start_object()
Handle the start of an object.
Probability, optimization and sampling library.
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 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.