40 using std::ostringstream;
41 using std::istringstream;
46 #include <Structure.h>
47 #include <Constructor.h>
68 template<
typename T>
unsigned int W10nJsonTransform::json_simple_type_array_worker(ostream *strm, T *values,
unsigned int indx, vector<unsigned int> *shape,
unsigned int currentDim,
bool flatten){
70 if(currentDim==0 || !flatten)
73 unsigned int currentDimSize = (*shape)[currentDim];
75 for(
unsigned int i=0; i<currentDimSize ;i++){
76 if(currentDim < shape->size()-1){
78 <<
" currentDim: " << currentDim
79 <<
" currentDimSize: " << currentDimSize
81 indx = json_simple_type_array_worker<T>(strm,values,indx,shape,currentDim+1, flatten);
82 if(i+1 != currentDimSize)
88 if(
typeid(T) ==
typeid(std::string)){
90 std::string val = ((std::string *) values)[indx++];
94 *strm << values[indx++];
99 if(currentDim==0 || !flatten)
105 void W10nJsonTransform::json_array_starter(ostream *strm, libdap::Array *a, std::string indent){
108 bool found_w10n_callback =
false;
110 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_callback: "<< w10n_callback << endl);
113 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - Processing Array of " << a->var()->type_name() << endl);
116 if(found_w10n_callback){
117 *strm << w10n_callback <<
"(";
120 *strm <<
"{" << endl;
122 std::string child_indent = indent + _indent_increment;
124 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - Writing variable metadata..." << endl);
126 writeVariableMetadata(strm,a,child_indent);
127 *strm <<
"," << endl;
129 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - Writing variable data..." << endl);
132 *strm << child_indent <<
"\"data\": ";
135 void W10nJsonTransform::json_array_ender(ostream *strm, std::string indent){
137 bool found_w10n_meta_object =
false;
139 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_ender() - w10n_meta_object: "<< w10n_meta_object << endl);
141 bool found_w10n_callback =
false;
143 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_callback: "<< w10n_callback << endl);
145 std::string child_indent = indent + _indent_increment;
148 if(found_w10n_meta_object)
149 *strm <<
"," << endl << child_indent << w10n_meta_object << endl;
153 *strm << indent <<
"}" << endl;
155 if(found_w10n_callback){
168 template<
typename T>
void W10nJsonTransform::json_simple_type_array_sender(ostream *strm, libdap::Array *a){
170 bool found_w10n_flatten =
false;
172 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_sender() - w10n_flatten: "<< w10n_flatten << endl);
174 int numDim = a->dimensions(
true);
175 vector<unsigned int> shape(numDim);
178 T *src =
new T[length];
180 unsigned int indx = json_simple_type_array_worker(strm, src, 0, &shape, 0, found_w10n_flatten);
184 BESDEBUG(
W10N_DEBUG_KEY,
"json_simple_type_array_sender() - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
193 void W10nJsonTransform::json_string_array_sender(ostream *strm, libdap::Array *a){
195 bool found_w10n_flatten =
false;
197 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_sender() - w10n_flatten: "<< w10n_flatten << endl);
199 int numDim = a->dimensions(
true);
200 vector<unsigned int> shape(numDim);
204 vector<std::string> sourceValues;
205 a->value(sourceValues);
206 unsigned int indx = json_simple_type_array_worker(strm, (std::string *)(&sourceValues[0]), 0, &shape, 0, found_w10n_flatten);
209 BESDEBUG(
W10N_DEBUG_KEY,
"json_simple_type_array_sender() - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
218 template<
typename T>
void W10nJsonTransform::json_simple_type_array(ostream *strm, libdap::Array *a, std::string indent){
221 bool found_w10n_meta_object =
false;
223 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_meta_object: "<< w10n_meta_object << endl);
225 bool found_w10n_callback =
false;
227 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_callback: "<< w10n_callback << endl);
229 bool found_w10n_flatten =
false;
231 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_flatten: "<< w10n_flatten << endl);
233 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - Processing Array of " << a->var()->type_name() << endl);
236 if(found_w10n_callback){
237 *strm << w10n_callback <<
"(";
241 *strm <<
"{" << endl;
243 string child_indent = indent + _indent_increment;
245 int numDim = a->dimensions(
true);
246 vector<unsigned int> shape(numDim);
249 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - Writing variable metadata..." << endl);
251 writeVariableMetadata(strm,a,child_indent);
252 *strm <<
"," << endl;
254 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - Writing variable data..." << endl);
257 *strm << child_indent <<
"\"data\": ";
260 T *src =
new T[length];
262 indx = json_simple_type_array_worker(strm, src, 0, &shape, 0, found_w10n_flatten);
266 BESDEBUG(
W10N_DEBUG_KEY,
"json_simple_type_array() - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
268 if(found_w10n_meta_object)
269 *strm <<
"," << endl << child_indent << w10n_meta_object << endl;
273 *strm << indent <<
"}" << endl;
275 if(found_w10n_callback){
283 json_array_starter(strm,a, indent);
284 json_simple_type_array_sender<T>(strm,a);
285 json_array_ender(strm, indent);
294 void W10nJsonTransform::json_string_array(ostream *strm, libdap::Array *a, std::string indent){
297 bool found_w10n_meta_object =
false;
299 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_string() - w10n_meta_object: "<< w10n_meta_object << endl);
301 bool found_w10n_callback =
false;
303 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_string() - w10n_callback: "<< w10n_callback << endl);
305 bool found_w10n_flatten =
false;
307 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_string() - w10n_flatten: "<< w10n_flatten << endl);
309 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_string() - Processing Array of " << a->var()->type_name() << endl);
312 if(found_w10n_callback){
313 *strm << w10n_callback <<
"(";
316 *strm <<
"{" << endl;
318 string child_indent = indent + _indent_increment;
320 int numDim = a->dimensions(
true);
321 vector<unsigned int> shape(numDim);
324 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_string() - Writing variable metadata..." << endl);
326 writeVariableMetadata(strm,a,child_indent);
327 *strm <<
"," << endl;
329 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array_string() - Writing variable data..." << endl);
332 *strm << child_indent <<
"\"data\": ";
336 vector<std::string> sourceValues;
337 a->value(sourceValues);
338 indx = json_simple_type_array_worker(strm, (std::string *)(&sourceValues[0]), 0, &shape, 0, found_w10n_flatten);
342 BESDEBUG(
W10N_DEBUG_KEY,
"json_simple_type_array_string() - indx NOT equal to content length! indx: " << indx <<
" length: " << length << endl);
345 if(found_w10n_meta_object)
346 *strm <<
"," << endl << child_indent << w10n_meta_object << endl;
350 *strm << indent <<
"}" << endl;
352 if(found_w10n_callback){
360 json_array_starter(strm,a, indent);
361 json_string_array_sender(strm,a);
362 json_array_ender(strm, indent);
370 void W10nJsonTransform::writeDatasetMetadata(ostream *strm, libdap::DDS *dds, std::string indent){
373 *strm << indent <<
"\"name\": \""<< dds->get_dataset_name() <<
"\"," << endl;
376 writeAttributes(strm, dds->get_attr_table(), indent);
377 *strm <<
"," << endl;
386 void W10nJsonTransform::writeVariableMetadata(ostream *strm, libdap::BaseType *bt, std::string indent){
389 *strm << indent <<
"\"name\": \""<< bt->name() <<
"\"," << endl;
390 libdap::BaseType *var = bt;
394 if(bt->type() == libdap::dods_array_c){
395 libdap::Array *a = (libdap::Array *)bt;
398 if(!var->is_constructor_type())
399 *strm << indent <<
"\"type\": \""<< var->type_name() <<
"\"," << endl;
402 writeAttributes(strm, bt->get_attr_table(), indent);
424 _dds(dds), _localfile(localfile), _indent_increment(
" "), _ostrm(0), _usingTempFile(false)
427 std::string msg =
"W10nJsonTransform: ERROR! A null DDS reference was passed to the constructor";
432 if (_localfile.empty()){
433 std::string msg =
"W10nJsonTransform: An empty local file name passed to constructor";
440 _dds(dds), _localfile(
""), _indent_increment(
" "), _ostrm(ostrm), _usingTempFile(false)
443 std::string msg =
"W10nJsonTransform: ERROR! A null DDS reference was passed to the constructor";
449 std::string msg =
"W10nJsonTransform: ERROR! A null std::ostream pointer was passed to the constructor";
474 strm <<
BESIndent::LMarg <<
"W10nJsonTransform::dump - (" << (
void *)
this <<
")" << endl;
488 void W10nJsonTransform::writeAttributes(ostream *strm, libdap::AttrTable &attr_table, std::string indent){
490 std::string child_indent = indent + _indent_increment;
493 *strm << indent <<
"\"attributes\": [";
501 if(attr_table.get_size() != 0) {
503 libdap::AttrTable::Attr_iter begin = attr_table.attr_begin();
504 libdap::AttrTable::Attr_iter end = attr_table.attr_end();
507 for(libdap::AttrTable::Attr_iter at_iter=begin; at_iter !=end; at_iter++){
509 switch (attr_table.get_attr_type(at_iter)){
510 case libdap::Attr_container:
512 libdap::AttrTable *atbl = attr_table.get_attr_table(at_iter);
515 if(at_iter != begin )
516 *strm <<
"," << endl;
519 *strm << child_indent <<
"{" << endl;
522 if(atbl->get_name().length()>0)
523 *strm << child_indent + _indent_increment <<
"\"name\": \"" << atbl->get_name() <<
"\"," << endl;
527 writeAttributes(strm, *atbl, child_indent + _indent_increment);
528 *strm << endl << child_indent <<
"}";
537 *strm <<
"," << endl;
540 *strm << child_indent <<
"{\"name\": \""<< attr_table.get_name(at_iter) <<
"\", ";
543 *strm <<
"\"value\": [";
544 vector<std::string> *values = attr_table.get_attr_vector(at_iter);
546 for(std::vector<std::string>::size_type i=0; i<values->size() ;i++){
553 if(attr_table.get_attr_type(at_iter) == libdap::Attr_string || attr_table.get_attr_type(at_iter) == libdap::Attr_url){
555 std::string value = (*values)[i] ;
561 *strm << (*values)[i] ;
572 *strm << endl << indent;
584 std::ostream *W10nJsonTransform::getOutputStream(){
586 _usingTempFile =
false;
587 std::fstream _tempFile;
590 _tempFile.open(_localfile.c_str(), std::fstream::out);
592 std::string msg =
"Could not open temp file: " + _localfile;
597 _usingTempFile =
true;
603 void W10nJsonTransform::releaseOutputStream(){
605 ((std::fstream *)_ostrm)->close();
613 std::ostream *strm = getOutputStream();
616 releaseOutputStream();
619 releaseOutputStream();
631 bool found_w10n_meta_object =
false;
633 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_meta_object: "<< w10n_meta_object << endl);
635 bool found_w10n_callback =
false;
637 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_callback: "<< w10n_callback << endl);
643 vector<libdap::BaseType *> leaves;
644 vector<libdap::BaseType *> nodes;
646 libdap::DDS::Vars_iter vi = dds->var_begin();
647 libdap::DDS::Vars_iter ve = dds->var_end();
648 for (; vi != ve; vi++) {
649 libdap::BaseType *v = *vi;
651 libdap::Type type = v->type();
652 if(type == libdap::dods_array_c){
653 type = v->var()->type();
655 if(v->is_constructor_type() ||
656 (v->is_vector_type() && v->var()->is_constructor_type())){
665 if(found_w10n_callback){
666 *strm << w10n_callback <<
"(";
671 *strm <<
"{" << endl ;
672 std::string child_indent = indent + _indent_increment;
675 writeDatasetMetadata(strm, dds, child_indent);
680 *strm << child_indent <<
"\"leaves\": [";
681 if(leaves.size() > 0)
683 for(std::vector<libdap::BaseType *>::size_type l=0; l< leaves.size(); l++){
684 libdap::BaseType *v = leaves[l];
687 *strm <<
"," << endl ;
690 sendW10nMetaForVariable(strm, v, child_indent + _indent_increment,
false);
693 *strm << endl << child_indent;
694 *strm <<
"]," << endl;
698 *strm << child_indent <<
"\"nodes\": [";
701 for(std::vector<libdap::BaseType *>::size_type n=0; n< nodes.size(); n++){
702 libdap::BaseType *v = nodes[n];
705 *strm <<
"," << endl ;
707 sendW10nMetaForVariable(strm, v, child_indent + _indent_increment,
false);
710 *strm << endl << child_indent;
715 if(found_w10n_meta_object)
716 *strm <<
"," << endl << child_indent << w10n_meta_object << endl;
722 if(found_w10n_callback){
731 void W10nJsonTransform::sendW10nMetaForVariable(ostream *strm, libdap::BaseType *bt, std::string indent,
bool isTop){
735 bool found_w10n_meta_object =
false;
737 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_meta_object: "<< w10n_meta_object << endl);
739 bool found_w10n_callback =
false;
741 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_callback: "<< w10n_callback << endl);
743 bool found_w10n_flatten =
false;
745 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_flatten: "<< w10n_flatten << endl);
748 bool found_w10n_traverse =
false;
750 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_traverse: "<< w10n_traverse << endl);
754 if(isTop && found_w10n_callback){
755 *strm << w10n_callback <<
"(";
759 *strm << indent <<
"{" << endl;\
761 std::string child_indent = indent + _indent_increment;
763 writeVariableMetadata(strm,bt,child_indent);
766 if(bt->type() == libdap::dods_array_c){
767 *strm <<
"," << endl;
769 libdap::Array *a = (libdap::Array *) bt;
770 int numDim = a->dimensions(
true);
771 vector<unsigned int> shape(numDim);
774 if(found_w10n_flatten){
775 *strm << child_indent <<
"\"shape\": [" << length <<
"]";
779 *strm << child_indent <<
"\"shape\": [";
780 for(std::vector<unsigned int>::size_type i=0; i<shape.size() ;i++){
789 if(bt->is_constructor_type() && (found_w10n_traverse || isTop)){
790 *strm <<
"," << endl;
792 libdap::Constructor *ctor = (libdap::Constructor *)bt;
794 vector<libdap::BaseType *> leaves;
795 vector<libdap::BaseType *> nodes;
796 libdap::Constructor::Vars_iter vi = ctor->var_begin();
797 libdap::Constructor::Vars_iter ve = ctor->var_end();
798 for (; vi != ve; vi++) {
799 libdap::BaseType *v = *vi;
801 libdap::Type type = v->type();
802 if(type == libdap::dods_array_c){
803 type = v->var()->type();
805 if(v->is_constructor_type() ||
806 (v->is_vector_type() && v->var()->is_constructor_type())){
816 *strm << child_indent <<
"\"leaves\": [";
817 if(leaves.size() > 0)
819 for(std::vector<libdap::BaseType *>::size_type l=0; l< leaves.size(); l++){
820 libdap::BaseType *v = leaves[l];
827 sendW10nMetaForVariable(strm, v, child_indent + _indent_increment,
false);
830 *strm << endl << child_indent;
831 *strm <<
"]," << endl;
835 *strm << child_indent <<
"\"nodes\": [";
838 for(std::vector<libdap::BaseType *>::size_type n=0; n< nodes.size(); n++){
839 libdap::BaseType *v = nodes[n];
842 *strm <<
"," << endl ;
844 sendW10nMetaForVariable(strm, v, child_indent + _indent_increment,
false);
847 *strm << endl << child_indent;
855 if(!bt->is_constructor_type()){
864 if(isTop && found_w10n_meta_object){
865 *strm <<
"," << endl << child_indent << w10n_meta_object << endl;
870 *strm << endl << indent <<
"}";
872 if(isTop && found_w10n_callback){
882 void W10nJsonTransform::sendW10nMetaForVariable(std::string &vName,
bool isTop){
885 libdap::BaseType *bt = _dds->var(vName);
888 std::string msg =
"The dataset does not contain a variable named '" + vName +
"'";
893 std::ostream *strm = getOutputStream();
895 sendW10nMetaForVariable(strm, bt,
"", isTop);
897 releaseOutputStream();
900 releaseOutputStream();
909 void W10nJsonTransform::sendW10nDataForVariable(std::string &vName){
912 libdap::BaseType *bt = _dds->var(vName);
915 std::string msg =
"The dataset does not contain a variable named '" + vName +
"'";
920 std::ostream *strm = getOutputStream();
922 sendW10nDataForVariable(strm, bt,
"");
923 releaseOutputStream();
926 releaseOutputStream();
932 void W10nJsonTransform::sendW10nDataForVariable(ostream *strm, libdap::BaseType *bt, std::string indent){
934 if(bt->is_simple_type()){
936 sendW10nData(strm, bt, indent);
939 else if(bt->type()==libdap::dods_array_c && bt->var()->is_simple_type()){
940 sendW10nData(strm, (libdap::Array *)bt, indent);
944 std::string msg =
"The variable '" + bt->name() +
"' is not a simple type or an Array of simple types. ";
945 msg +=
"The w10n protocol does not support the transmission of data for complex types.";
958 void W10nJsonTransform::sendW10nData(ostream *strm, libdap::BaseType *b, std::string indent){
960 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::sendW10nData() - Sending data for simple type "<< b->name() << endl);
962 bool found_w10n_meta_object =
false;
964 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_meta_object: "<< w10n_meta_object << endl);
966 bool found_w10n_callback =
false;
968 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_callback: "<< w10n_callback << endl);
970 bool found_w10n_flatten =
false;
972 BESDEBUG(
W10N_DEBUG_KEY,
"W10nJsonTransform::json_simple_type_array() - w10n_flatten: "<< w10n_flatten << endl);
978 std::string child_indent = indent + _indent_increment;
980 if(found_w10n_callback){
981 *strm << w10n_callback <<
"(";
985 *strm <<
"{" << endl;
987 writeVariableMetadata(strm,b,child_indent);
988 *strm <<
"," << endl;
991 *strm << child_indent <<
"\"data\": ";
993 if(b->type() == libdap::dods_str_c || b->type() == libdap::dods_url_c ){
994 libdap::Str *strVar = (libdap::Str *)b;
998 b->print_val(*strm,
"",
false);
1003 if(found_w10n_meta_object)
1004 *strm <<
"," << endl << child_indent << w10n_meta_object << endl;
1010 if(found_w10n_callback){
1021 void W10nJsonTransform::sendW10nData(ostream *strm, libdap::Array *a, std::string indent){
1025 <<
" a->type_name(): " << a->type_name()
1026 <<
" a->var()->type_name(): " << a->var()->type_name()
1029 switch(a->var()->type()){
1031 case libdap::dods_byte_c:
1032 json_simple_type_array<libdap::dods_byte>(strm,a,indent);
1035 case libdap::dods_int16_c:
1036 json_simple_type_array<libdap::dods_int16>(strm,a,indent);
1039 case libdap::dods_uint16_c:
1040 json_simple_type_array<libdap::dods_uint16>(strm,a,indent);
1043 case libdap::dods_int32_c:
1044 json_simple_type_array<libdap::dods_int32>(strm,a,indent);
1047 case libdap::dods_uint32_c:
1048 json_simple_type_array<libdap::dods_uint32>(strm,a,indent);
1051 case libdap::dods_float32_c:
1052 json_simple_type_array<libdap::dods_float32>(strm,a,indent);
1055 case libdap::dods_float64_c:
1056 json_simple_type_array<libdap::dods_float64>(strm,a,indent);
1059 case libdap::dods_str_c:
1061 json_string_array(strm,a,indent);
1064 string s = (string)
"W10nJsonTransform: Arrays of String objects not a supported return type.";
1071 case libdap::dods_url_c:
1073 json_string_array(strm,a,indent);
1077 string s = (string)
"W10nJsonTransform: Arrays of URL objects not a supported return type.";
1084 case libdap::dods_structure_c:
1086 std::string s = (std::string)
"W10nJsonTransform: Arrays of Structure objects not a supported return type.";
1091 case libdap::dods_grid_c:
1093 std::string s = (std::string)
"W10nJsonTransform: Arrays of Grid objects not a supported return type.";
1099 case libdap::dods_sequence_c:
1101 std::string s = (std::string)
"W10nJsonTransform: Arrays of Sequence objects not a supported return type.";
1107 case libdap::dods_array_c:
1109 std::string s = (std::string)
"W10nJsonTransform: Arrays of Array objects not a supported return type.";
1114 case libdap::dods_int8_c:
1115 case libdap::dods_uint8_c:
1116 case libdap::dods_int64_c:
1117 case libdap::dods_uint64_c:
1119 case libdap::dods_enum_c:
1120 case libdap::dods_group_c:
1122 std::string s = (std::string)
"W10nJsonTransform: DAP4 types not yet supported.";
1130 std::string s = (std::string)
"W10nJsonTransform: Unrecognized type.";
exception thrown if inernal error encountered
#define W10N_TRAVERSE_KEY
std::string escape_for_json(const std::string &input)
#define W10N_META_OBJECT_KEY
virtual string get_context(const string &name, bool &found)
retrieve the value of the specified context from the BES
error thrown if there is a user syntax error in the request or any other user error ...
#define W10N_CALLBACK_KEY
static ostream & LMarg(ostream &strm)
static BESContextManager * TheManager()
long computeConstrainedShape(libdap::Array *a, std::vector< unsigned int > *shape)
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