39 #include <Structure.h>
40 #include <Constructor.h>
55 #define ATTRIBUTE_SEPARATOR "."
56 #define JSON_ORIGINAL_NAME "json_original_name"
58 #define FoInstanceJsonTransform_debug_key "fojson"
63 template<
typename T>
unsigned int FoInstanceJsonTransform::json_simple_type_array_worker(std::ostream *strm,
const std::vector<T> &values,
64 unsigned int indx,
const std::vector<unsigned int> &shape,
unsigned int currentDim)
68 unsigned int currentDimSize = shape.at(currentDim);
70 for (
unsigned int i = 0; i < currentDimSize; i++) {
71 if (currentDim < shape.size() - 1) {
73 "json_simple_type_array_worker() - Recursing! indx: " << indx <<
" currentDim: " << currentDim
74 <<
" currentDimSize: " << currentDimSize << endl);
76 indx = json_simple_type_array_worker<T>(strm, values, indx, shape, currentDim + 1);
77 if (i + 1 != currentDimSize) *strm <<
", ";
81 *strm << values[indx++];
98 template<
typename T>
void FoInstanceJsonTransform::json_simple_type_array(std::ostream *strm, libdap::Array *a, std::string indent,
101 std::string name = a->name();
106 std::vector<unsigned int> shape(a->dimensions(
true));
109 vector<T> src(length);
111 unsigned int indx = json_simple_type_array_worker(strm, src, 0, shape, 0);
116 "json_simple_type_array() - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
119 *strm <<
"{" << endl;
121 transform(strm, a->get_attr_table(), indent + _indent_increment);
122 *strm << endl << indent <<
"}";
135 void FoInstanceJsonTransform::json_string_array(std::ostream *strm, libdap::Array *a, std::string indent,
bool sendData)
137 std::string name = a->name();
141 std::vector<unsigned int> shape(a->dimensions(
true));
145 std::vector<std::string> sourceValues;
146 a->value(sourceValues);
148 unsigned int indx = json_simple_type_array_worker(strm, sourceValues, 0, shape, 0);
153 << indx <<
" length: " << length << endl);
156 *strm <<
"{" << endl;
158 transform(strm, a->get_attr_table(), indent + _indent_increment);
159 *strm << endl << indent <<
"}";
178 _dds(dds), _localfile(localfile), _indent_increment(
" "), _ostrm(0)
182 if (!_dds)
throw BESInternalError(
"File out JSON, null DDS passed to constructor", __FILE__, __LINE__);
183 if (_localfile.empty())
184 throw BESInternalError(
"File out JSON, empty local file name passed to constructor", __FILE__, __LINE__);
199 _dds(dds), _localfile(
""), _indent_increment(
" "), _ostrm(ostrm)
202 if (!_dds)
throw BESInternalError(
"File out JSON, null DDS passed to constructor", __FILE__, __LINE__);
224 strm <<
BESIndent::LMarg <<
"FoInstanceJsonTransform::dump - (" << (
void *)
this <<
")" << endl;
245 void FoInstanceJsonTransform::transform(
bool sendData)
248 bool used_temp_file =
false;
254 temp_file.open(_localfile.c_str(), std::fstream::out);
255 if (!temp_file)
throw BESInternalError(
"Could not open temp file: " + _localfile, __FILE__, __LINE__);
257 used_temp_file =
true;
261 transform(_ostrm, _dds,
"", sendData);
262 if (used_temp_file) temp_file.close();
265 if (used_temp_file) temp_file.close();
280 void FoInstanceJsonTransform::transform(std::ostream *strm, libdap::DDS *dds,
string indent,
bool sendData)
283 bool sentSomething =
false;
286 *strm <<
"{" << endl;
289 std::string name = dds->get_dataset_name();
296 transform(strm, dds->get_attr_table(), indent);
297 if (dds->get_attr_table().get_size() > 0) *strm <<
",";
302 if (dds->num_var() > 0) {
304 libdap::DDS::Vars_iter vi = dds->var_begin();
305 libdap::DDS::Vars_iter ve = dds->var_end();
306 for (; vi != ve; vi++) {
307 if ((*vi)->send_p()) {
309 libdap::BaseType *v = *vi;
316 transform(strm, v, indent + _indent_increment, sendData);
318 sentSomething =
true;
325 *strm << endl <<
"}" << endl;
338 void FoInstanceJsonTransform::transform(std::ostream *strm, libdap::BaseType *bt,
string indent,
bool sendData)
340 switch (bt->type()) {
342 case libdap::dods_byte_c:
343 case libdap::dods_int16_c:
344 case libdap::dods_uint16_c:
345 case libdap::dods_int32_c:
346 case libdap::dods_uint32_c:
347 case libdap::dods_float32_c:
348 case libdap::dods_float64_c:
349 case libdap::dods_str_c:
350 case libdap::dods_url_c:
351 transformAtomic(strm, bt, indent, sendData);
354 case libdap::dods_structure_c:
355 transform(strm, (libdap::Structure *) bt, indent, sendData);
358 case libdap::dods_grid_c:
359 transform(strm, (libdap::Grid *) bt, indent, sendData);
362 case libdap::dods_sequence_c:
363 transform(strm, (libdap::Sequence *) bt, indent, sendData);
366 case libdap::dods_array_c:
367 transform(strm, (libdap::Array *) bt, indent, sendData);
370 case libdap::dods_int8_c:
371 case libdap::dods_uint8_c:
372 case libdap::dods_int64_c:
373 case libdap::dods_uint64_c:
376 case libdap::dods_enum_c:
377 case libdap::dods_group_c: {
378 string s = (string)
"File out JSON, " +
"DAP4 types not yet supported.";
384 string s = (string)
"File out JSON, " +
"Unrecognized type.";
403 void FoInstanceJsonTransform::transformAtomic(std::ostream *strm, libdap::BaseType *b,
string indent,
bool sendData)
405 std::string name = b->name();
410 if (b->type() == libdap::dods_str_c || b->type() == libdap::dods_url_c) {
411 libdap::Str *strVar = (libdap::Str *) b;
412 std::string tmpString = strVar->value();
416 b->print_val(*strm,
"",
false);
421 transform(strm, b->get_attr_table(), indent);
434 void FoInstanceJsonTransform::transform(std::ostream *strm, libdap::Structure *b,
string indent,
bool sendData)
438 std::string name = b->name();
442 if (b->width(
true) > 0) {
444 libdap::Structure::Vars_iter vi = b->var_begin();
445 libdap::Structure::Vars_iter ve = b->var_end();
446 for (; vi != ve; vi++) {
449 if ((*vi)->send_p()) {
450 libdap::BaseType *v = *vi;
452 "FoInstanceJsonTransform::transform() - Processing structure variable: " << v->name() << endl);
453 transform(strm, v, indent + _indent_increment, sendData);
454 if ((vi + 1) != ve) {
461 *strm << indent <<
"}";
473 void FoInstanceJsonTransform::transform(std::ostream *strm, libdap::Grid *g,
string indent,
bool sendData)
477 std::string name = g->name();
481 "FoInstanceJsonTransform::transform() - Processing Grid data Array: " << g->get_array()->name() << endl);
484 transform(strm, g->get_array(), indent + _indent_increment, sendData);
485 *strm <<
"," << endl;
488 for (libdap::Grid::Map_iter mapi = g->map_begin(); mapi < g->map_end(); mapi++) {
490 "FoInstanceJsonTransform::transform() - Processing Grid Map Array: " << (*mapi)->name() << endl);
491 if (mapi != g->map_begin()) {
492 *strm <<
"," << endl;
494 transform(strm, *mapi, indent + _indent_increment, sendData);
497 *strm << endl << indent <<
"}";
510 void FoInstanceJsonTransform::transform(std::ostream *strm, libdap::Sequence *s,
string indent,
bool sendData)
514 std::string name = s->name();
517 string child_indent = indent + _indent_increment;
521 *strm << indent <<
"\"table\": {" << endl;
523 string child_indent = indent + _indent_increment;
525 *strm << child_indent <<
"\"name\": \"" << s->name() <<
"\"," << endl;
529 *strm << child_indent <<
"\"columnNames\": [";
530 for (libdap::Constructor::Vars_iter v = s->var_begin(); v < s->var_end(); v++) {
531 if (v != s->var_begin())
533 std::string name = (*v)->name();
536 *strm <<
"]," << endl;
538 *strm << child_indent <<
"\"columnTypes\": [";
539 for (libdap::Constructor::Vars_iter v = s->var_begin(); v < s->var_end(); v++) {
540 if (v != s->var_begin()) *strm <<
",";
541 *strm <<
"\"" << (*v)->type_name() <<
"\"";
543 *strm <<
"]," << endl;
546 *strm << child_indent <<
"\"rows\": [";
548 if (!first) *strm <<
", ";
549 *strm << endl << child_indent <<
"[";
550 for (libdap::Constructor::Vars_iter v = s->var_begin(); v < s->var_end(); v++) {
551 if (v != s->var_begin()) *strm << child_indent <<
",";
552 transform(strm, (*v), child_indent + _indent_increment, sendData);
554 *strm << child_indent <<
"]";
557 *strm << endl << child_indent <<
"]" << endl;
560 *strm << indent <<
"}" << endl;
572 void FoInstanceJsonTransform::transform(std::ostream *strm, libdap::Array *a,
string indent,
bool sendData)
576 "FoInstanceJsonTransform::transform() - Processing Array. " <<
" a->type(): " << a->type() <<
" a->var()->type(): " << a->var()->type() << endl);
578 switch (a->var()->type()) {
580 case libdap::dods_byte_c:
581 json_simple_type_array<libdap::dods_byte>(strm, a, indent, sendData);
584 case libdap::dods_int16_c:
585 json_simple_type_array<libdap::dods_int16>(strm, a, indent, sendData);
588 case libdap::dods_uint16_c:
589 json_simple_type_array<libdap::dods_uint16>(strm, a, indent, sendData);
592 case libdap::dods_int32_c:
593 json_simple_type_array<libdap::dods_int32>(strm, a, indent, sendData);
596 case libdap::dods_uint32_c:
597 json_simple_type_array<libdap::dods_uint32>(strm, a, indent, sendData);
600 case libdap::dods_float32_c:
601 json_simple_type_array<libdap::dods_float32>(strm, a, indent, sendData);
604 case libdap::dods_float64_c:
605 json_simple_type_array<libdap::dods_float64>(strm, a, indent, sendData);
608 case libdap::dods_str_c: {
609 json_string_array(strm, a, indent, sendData);
613 string s = (string)
"File out JSON, " +
"Arrays of Strings are not yet a supported return type.";
620 case libdap::dods_url_c: {
621 json_string_array(strm, a, indent, sendData);
625 string s = (string)
"File out JSON, " +
"Arrays of URLs are not yet a supported return type.";
632 case libdap::dods_structure_c: {
633 string s = (string)
"File out JSON, " +
"Arrays of Structure objects not a supported return type.";
637 case libdap::dods_grid_c: {
638 string s = (string)
"File out JSON, " +
"Arrays of Grid objects not a supported return type.";
643 case libdap::dods_sequence_c: {
644 string s = (string)
"File out JSON, " +
"Arrays of Sequence objects not a supported return type.";
649 case libdap::dods_array_c: {
650 string s = (string)
"File out JSON, " +
"Arrays of Array objects not a supported return type.";
654 case libdap::dods_int8_c:
655 case libdap::dods_uint8_c:
656 case libdap::dods_int64_c:
657 case libdap::dods_uint64_c:
659 case libdap::dods_enum_c:
660 case libdap::dods_group_c: {
661 string s = (string)
"File out JSON, " +
"DAP4 types not yet supported.";
667 string s = (string)
"File out JSON, " +
"Unrecognized type.";
688 void FoInstanceJsonTransform::transform(std::ostream *strm, libdap::AttrTable &attr_table,
string indent)
696 string child_indent = indent + _indent_increment;
699 if (attr_table.get_size() != 0) {
701 libdap::AttrTable::Attr_iter begin = attr_table.attr_begin();
702 libdap::AttrTable::Attr_iter end = attr_table.attr_end();
705 for (libdap::AttrTable::Attr_iter at_iter = begin; at_iter != end; at_iter++) {
707 switch (attr_table.get_attr_type(at_iter)) {
709 case libdap::Attr_container:
711 libdap::AttrTable *atbl = attr_table.get_attr_table(at_iter);
713 if (at_iter != begin) *strm <<
"," << endl;
716 std::string name = atbl->get_name();
720 transform(strm, *atbl, child_indent + _indent_increment);
723 *strm << endl << child_indent <<
"}";
730 if (at_iter != begin) *strm <<
"," << endl;
733 std::string name = attr_table.get_name(at_iter);
739 std::vector<std::string> *values = attr_table.get_attr_vector(at_iter);
740 for (std::vector<std::string>::size_type i = 0; i < values->size(); i++) {
741 if (i > 0) *strm <<
",";
742 if (attr_table.get_attr_type(at_iter) == libdap::Attr_string
743 || attr_table.get_attr_type(at_iter) == libdap::Attr_url) {
746 string value = (*values)[i];
751 *strm << (*values)[i];
exception thrown if inernal error encountered
static ostream & LMarg(ostream &strm)
long computeConstrainedShape(libdap::Array *a, std::vector< unsigned int > *shape)
Compute the constrained shape of the Array and return it in a vector.
std::string escape_for_json(const std::string &input)
Structure storing information used by the BES to handle the request.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream