26#if defined (HAVE_CONFIG_H)
30#include "builtin-defun-decls.h"
37#if defined (HAVE_RAPIDJSON)
38# include <rapidjson/stringbuffer.h>
39# include <rapidjson/writer.h>
40# if defined (HAVE_RAPIDJSON_PRETTYWRITER)
41# include <rapidjson/prettywriter.h>
45#if defined (HAVE_RAPIDJSON)
60template <
typename T>
void
62 const bool& ConvertInfAndNaN)
73 if (fabs (
trunc (value) - value) < std::numeric_limits<double>::epsilon ())
77 else if (ConvertInfAndNaN && ! octave::math::isfinite (value))
80 writer.Double (value);
87 writer.Uint64 (value);
100 error (
"jsonencode: unsupported type");
117template <
typename T>
void
119 const dim_vector& original_dims,
int level = 0)
132 std::string char_vector =
"";
134 char_vector += array(i);
135 writer.String (char_vector.c_str ());
140 std::string char_vector =
"";
142 char_vector += array(i * original_dims(1) + k);
143 writer.String (char_vector.c_str ());
162 for (
int i = level; i < ndims - 1; ++i)
163 writer.StartArray ();
165 encode_string (writer, array.
as_row (), original_dims, level);
168 for (
int i = level; i < ndims - 1; ++i)
176 if (original_dims(level) == 1 && level != 1)
178 writer.StartArray ();
179 encode_string (writer, array, original_dims, level + 1);
189 for (idx = 0; idx < ndims; ++idx)
198 conversion_dims.
resize (ndims - 1);
200 conversion_dims(i) = i + 1;
202 conversion_dims(i) = i + 2;
205 args.append (conversion_dims);
207 Cell sub_arrays = octave::Fnum2cell (args)(0).cell_value ();
209 writer.StartArray ();
212 encode_string (writer, sub_arrays(i), original_dims,
235template <
typename T>
void
236encode_struct (T& writer,
const octave_value& obj,
const bool& ConvertInfAndNaN)
240 bool is_array = (
numel != 1);
244 writer.StartArray ();
248 writer.StartObject ();
251 writer.Key (keys(k).c_str ());
252 encode (writer, struct_array(i).getfield (keys(k)), ConvertInfAndNaN);
274template <
typename T>
void
275encode_cell (T& writer,
const octave_value& obj,
const bool& ConvertInfAndNaN)
279 writer.StartArray ();
282 encode (writer, cell(i), ConvertInfAndNaN);
303template <
typename T>
void
304encode_array (T& writer,
const octave_value& obj,
const bool& ConvertInfAndNaN,
305 const dim_vector& original_dims,
int level = 0,
306 bool is_logical =
false)
316 writer.StartArray ();
321 writer.StartArray ();
325 encode_numeric (writer,
bool (array(i)), ConvertInfAndNaN);
327 encode_numeric (writer, array(i), ConvertInfAndNaN);
347 for (
int i = level; i < ndims - 1; ++i)
348 writer.StartArray ();
350 encode_array (writer, array.
as_row (), ConvertInfAndNaN,
351 original_dims, level + 1, is_logical);
354 for (
int i = level; i < ndims - 1; ++i)
362 if (original_dims (level) == 1)
364 writer.StartArray ();
365 encode_array (writer, array, ConvertInfAndNaN,
366 original_dims, level + 1, is_logical);
371 for (idx = 0; idx < ndims; ++idx)
381 conversion_dims.
resize (ndims - 1);
383 conversion_dims(i) = i + 1;
385 conversion_dims(i) = i + 2;
388 args.append (conversion_dims);
390 Cell sub_arrays = octave::Fnum2cell (args)(0).cell_value ();
392 writer.StartArray ();
395 encode_array (writer, sub_arrays(i), ConvertInfAndNaN,
396 original_dims, level + 1, is_logical);
418template <
typename T>
void
419encode (T& writer,
const octave_value& obj,
const bool& ConvertInfAndNaN)
423 encode_numeric (writer, obj, ConvertInfAndNaN);
426 encode_array (writer, obj, ConvertInfAndNaN, obj.
dims ());
428 encode_string (writer, obj, obj.
dims ());
430 encode_struct (writer, obj, ConvertInfAndNaN);
432 encode_cell (writer, obj, ConvertInfAndNaN);
433 else if (obj.
class_name () ==
"containers.Map")
440 octave::unwind_action restore_warning_state
443 octave::set_warning_state (old_warning_state);
444 }, octave::set_warning_state (
"Octave:classdef-to-struct",
"off"));
451 octave::unwind_action restore_warning_state
454 octave::set_warning_state (old_warning_state);
455 }, octave::set_warning_state (
"Octave:classdef-to-struct",
"off"));
460 error (
"jsonencode: unsupported type");
467DEFUN (jsonencode, args, ,
606#if defined (HAVE_RAPIDJSON)
608 int nargin = args.length ();
610 if (nargin != 1 && nargin != 3 && nargin != 5)
614 bool ConvertInfAndNaN =
true;
615 bool PrettyPrint =
false;
619 if (! args(i).is_string ())
620 error (
"jsonencode: option must be a string");
621 if (! args(i+1).is_bool_scalar ())
622 error (
"jsonencode: option value must be a logical scalar");
624 std::string option_name = args(i++).string_value ();
625 if (string::strcmpi (option_name,
"ConvertInfAndNaN"))
626 ConvertInfAndNaN = args(i).bool_value ();
627 else if (string::strcmpi (option_name,
"PrettyPrint"))
628 PrettyPrint = args(i).bool_value ();
630 error (
"jsonencode: "
631 R
"(Valid options are "ConvertInfAndNaN" and "PrettyPrint")");
634# if ! defined (HAVE_RAPIDJSON_PRETTYWRITER)
638 R
"(the "PrettyPrint" option of RapidJSON)");
643 rapidjson::StringBuffer json;
646# if defined (HAVE_RAPIDJSON_PRETTYWRITER)
647 rapidjson::PrettyWriter<rapidjson::StringBuffer, rapidjson::UTF8<>,
648 rapidjson::UTF8<>, rapidjson::CrtAllocator,
649 rapidjson::kWriteNanAndInfFlag> writer (json);
650 writer.SetIndent (
' ', 2);
651 encode (writer, args(0), ConvertInfAndNaN);
656 rapidjson::Writer<rapidjson::StringBuffer, rapidjson::UTF8<>,
657 rapidjson::UTF8<>, rapidjson::CrtAllocator,
658 rapidjson::kWriteNanAndInfFlag> writer (json);
659 encode (writer, args(0), ConvertInfAndNaN);
666 octave_unused_parameter (args);
694OCTAVE_END_NAMESPACE(octave)
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
bool isvector() const
Size of the specified dimension.
int ndims() const
Size of the specified dimension.
Array< T, Alloc > as_row() const
Return the array as a row vector.
bool isempty() const
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
void resize(octave_idx_type n, const double &rfv=0)
Vector representing the dimensions (size) of an Array.
string_vector keys() const
octave_idx_type numel() const
octave_value getfield(const std::string &key) const
uint64_t uint64_value(bool req_int=false, bool frc_str_conv=false) const
std::string class_name() const
bool bool_value(bool warn=false) const
bool is_real_scalar() const
int64_t int64_value(bool req_int=false, bool frc_str_conv=false) const
octave_scalar_map scalar_map_value() const
charNDArray char_array_value(bool frc_str_conv=false) const
bool is_uint64_type() const
double scalar_value(bool frc_str_conv=false) const
octave_map map_value() const
NDArray array_value(bool frc_str_conv=false) const
bool is_bool_scalar() const
octave_idx_type numel() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
void error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
void warn_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
std::complex< T > trunc(const std::complex< T > &x)
T::size_type numel(const T &str)