47 #include "D4Attributes.h"
49 #include "D4Dimensions.h"
52 #include "D4EnumDefs.h"
54 #include "XMLWriter.h"
58 #include "InternalErr.h"
65 Array::dimension::dimension(D4Dimension *d) : dim(d), use_sdim_for_slice(true)
77 Array::_duplicate(
const Array &a)
83 d_maps =
new D4Maps(*(a.d_maps));
107 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
111 length *= (*i).c_size > 0 ? (*i).c_size : 1;
138 :
Vector(n, 0, dods_array_c, is_dap4), d_maps(0)
157 :
Vector(n, d, 0, dods_array_c, is_dap4), d_maps(0)
177 return new Array(*
this);
181 Array::operator=(
const Array &rhs)
186 dynamic_cast<Vector &
>(*this) = rhs;
196 DBG(cerr << __func__ <<
"() - BEGIN (array:" <<
name() <<
")" << endl;);
201 DBG(cerr << __func__ <<
"() - Already DAP4 type: Just making a copy and adding to container. " << endl;);
203 DBG(cerr << __func__ <<
"() - END (Already DAP4 type)" << endl;);
211 for (
Array::Dim_iter dap2_dim = dest->dim_begin(), e = dest->dim_end(); dap2_dim != e; ++dap2_dim) {
212 if (!(*dap2_dim).name.empty()) {
213 DBG(cerr << __func__ <<
"() - Processing the array dimension '" << (*dap2_dim).name <<
"'" << endl;);
216 D4Dimension *d4_dim = root_dims->find_dim((*dap2_dim).name);
218 d4_dim =
new D4Dimension((*dap2_dim).name, (*dap2_dim).size);
220 DBG(cerr << __func__ <<
"() -" <<
221 " Added NEW D4Dimension '"<< d4_dim->name() <<
"' (" <<
222 (
void *)d4_dim <<
") to root->dims()"<< endl;);
225 DBG(cerr << __func__ <<
"() -" <<
226 " Using Existing D4Dimension '"<< d4_dim->name() <<
"' (" <<
227 (
void *)d4_dim <<
")"<< endl;);
229 if (d4_dim->size() != (
unsigned long) (*dap2_dim).size) {
241 d4_dim =
new D4Dimension((*dap2_dim).name +
"_" +
name(), (*dap2_dim).size);
242 DBG(cerr << __func__ <<
"() -" <<
243 " Utilizing Name/Size Conflict Naming Artifice. name'"<< d4_dim->name() <<
"' (" <<
244 (
void *)d4_dim <<
")"<< endl;);
250 (*dap2_dim).dim = d4_dim;
257 dest->set_is_dap4(
true);
259 DBG(cerr << __func__ <<
"() - END (array:" <<
name() <<
")" << endl;);
262 bool Array::is_dap2_grid(){
263 bool is_grid =
false;
265 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' is DAP4 object!" << endl;)
266 D4Maps *d4_maps = this->maps();
267 is_grid = d4_maps->size();
269 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' has D4Maps." << endl;)
271 D4Maps::D4MapsIter i = d4_maps->map_begin();
272 D4Maps::D4MapsIter e = d4_maps->map_end();
274 DBG( cerr << __func__ <<
"() - Map '"<< (*i)->array()->name() <<
" has " << (*i)->array()->_shape.size() <<
" dimension(s)." << endl;)
275 if((*i)->array()->_shape.size() > 1){
285 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' has no D4Maps." << endl;)
288 DBG( cerr << __func__ <<
"() - is_grid: "<< (is_grid?
"true":
"false") << endl;)
307 std::vector<BaseType *> *
309 DBG(cerr << __func__ <<
"() - BEGIN Array '"<<
name() <<
"'" << endl;);
317 DBG(cerr << __func__ <<
"() - Array '"<<
name() <<
"' is dap2 Grid!" << endl;);
321 g->set_array(grid_array);
325 g->set_attr_table(*grid_attrs);
335 D4Maps *d4_maps = this->maps();
336 vector<BaseType *> dropped_maps;
337 D4Maps::D4MapsIter miter = d4_maps->map_begin();
338 D4Maps::D4MapsIter end = d4_maps->map_end();
339 for( ; miter!=end; miter++){
340 D4Map *d4_map = (*miter);
341 Array *d4_map_array =
const_cast<Array*
>(d4_map->array());
342 vector<BaseType *> *d2_result = d4_map_array->
transform_to_dap2(&(g->get_attr_table()));
344 if(d2_result->size()>1)
345 throw Error(internal_error,
string(__func__)+
"() - ERROR: D4Map Array conversion resulted in multiple DAP2 objects.");
348 Array *d2_map_array =
dynamic_cast<Array *
>((*d2_result)[0]);
351 throw Error(internal_error,
string(__func__)+
"() - ERROR: DAP2 array from D4Map Array conversion has more than 1 dimension.");
353 g->add_map(d2_map_array,
false);
355 DBG( cerr << __func__ <<
"() - " <<
356 "DAS For Grid Map '" << d2_map_array->
name() <<
"':" << endl;
360 throw Error(internal_error,
string(__func__)+
"() - Unable to interpret returned DAP2 content.");
365 dropped_maps.push_back(d4_map_array);
370 if(!dropped_maps.empty()){
372 AttrTable *dv_table = Constructor::make_dropped_vars_attr_table(&dropped_maps);
373 dest->get_attr_table().append_container(dv_table,dv_table->
get_name());
378 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' is not a Grid!" << endl);
379 BaseType *proto = this->prototype();
380 switch(proto->
type()){
397 dest->set_attr_table(*attrs);
398 dest->set_is_dap4(
false);
400 DBG( cerr << __func__ <<
"() - " <<
401 "DAS for new Array '" << dest->name() <<
"':" << endl;
415 vector<BaseType *> *result;
417 result =
new vector<BaseType *>();
418 result->push_back(dest);
423 DBG( cerr << __func__ <<
"() - END Array '"<<
name() <<
"'" << endl;);
441 std::vector<dimension>::iterator i = _shape.begin(), e = _shape.end();
444 while (old_i != old_e) {
445 if ((*i).dim == *old_i) {
446 (*i).dim = new_dims->find_dim((*old_i)->name());
485 if (v && v->
type() == dods_array_c) {
507 if (v && v->
type() == dods_array_c) {
509 Vector::add_var_nocopy(a.
var());
518 Vector::add_var_nocopy(v);
561 _shape.insert(_shape.begin(), d);
571 _shape.insert(_shape.begin(), d);
595 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
597 (*i).stop = (*i).size - 1;
599 (*i).c_size = (*i).size;
623 static const char *array_sss = \
624 "Invalid constraint parameters: At least one of the start, stride or stop \n\
625 specified do not match the array variable.";
661 if (start >= d.
size || stop >= d.
size || stride > d.
size || stride <= 0)
662 throw Error(malformed_expr, array_sss);
664 if (((stop - start) / stride + 1) > d.
size)
665 throw Error(malformed_expr, array_sss);
671 d.
c_size = (stop - start) / stride + 1;
673 DBG(cerr <<
"add_constraint: c_size = " << d.
c_size << endl);
685 if (dim->constrained())
686 add_constraint(i, dim->c_start(), dim->c_stride(), dim->c_stop());
688 dim->set_used_by_projected_var(
true);
692 d.use_sdim_for_slice =
true;
699 return _shape.begin() ;
706 return _shape.end() ;
722 return _shape.size();
747 if (!_shape.empty()) {
778 return (!_shape.empty()) ? (*i).start : 0;
802 return (!_shape.empty()) ? (*i).stop : 0;
827 return (!_shape.empty()) ? (*i).stride : 0;
850 "*This* array has no dimensions.");
855 Array::dimension_D4dim(Dim_iter i)
857 return (!_shape.empty()) ? (*i).dim : 0;
863 if (!d_maps) d_maps =
new D4Maps(
this);
885 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
893 class PrintD4ArrayDimXMLWriter:
public unary_function<Array::dimension&, void> {
900 PrintD4ArrayDimXMLWriter(XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) { }
902 void operator()(Array::dimension &d)
908 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"Dim") < 0)
909 throw InternalErr(__FILE__, __LINE__,
"Could not write Dim element");
911 string name = (d.dim) ? d.dim->fully_qualified_name() : d.name;
914 if (!d_constrained && !name.empty()) {
915 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
916 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
918 else if (d.use_sdim_for_slice) {
919 assert(!name.empty());
920 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
921 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
925 size << (d_constrained ? d.c_size : d.size);
926 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size",
927 (
const xmlChar*) size.str().c_str()) < 0)
928 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
931 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
932 throw InternalErr(__FILE__, __LINE__,
"Could not end Dim element");
936 class PrintD4ConstructorVarXMLWriter:
public unary_function<BaseType*, void> {
940 PrintD4ConstructorVarXMLWriter(XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) { }
942 void operator()(BaseType *btp)
944 btp->print_dap4(xml, d_constrained);
948 class PrintD4MapXMLWriter:
public unary_function<D4Map*, void> {
952 PrintD4MapXMLWriter(XMLWriter &xml) : xml(xml) { }
954 void operator()(D4Map *m)
968 if (constrained && !
send_p())
return;
970 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
var()->
type_name().c_str()) < 0)
974 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
975 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
978 if (
var()->
type() == dods_enum_c) {
980 string path = e->enumeration()->name();
981 if (e->enumeration()->parent()) {
983 path =
static_cast<D4Group*
>(e->enumeration()->parent()->parent())->
FQN() + path;
985 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"enum", (
const xmlChar*)path.c_str()) < 0)
986 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for enum");
991 for_each(c.
var_begin(), c.
var_end(), PrintD4ConstructorVarXMLWriter(xml, constrained));
996 for_each(
dim_begin(),
dim_end(), PrintD4ArrayDimXMLWriter(xml, constrained));
1000 for_each(maps()->map_begin(), maps()->map_end(), PrintD4MapXMLWriter(xml));
1002 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1025 bool constraint_info,
bool constrained)
1028 print_decl(oss, space, print_semi, constraint_info, constrained);
1029 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
1049 void Array::print_decl(ostream &out,
string space,
bool print_semi,
bool constraint_info,
bool constrained)
1051 if (constrained && !
send_p())
return;
1054 var()->
print_decl(out, space,
false, constraint_info, constrained);
1056 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
1058 if ((*i).name !=
"") {
1059 out <<
id2www((*i).name) <<
" = ";
1062 out << (*i).c_size <<
"]";
1065 out << (*i).size <<
"]";
1081 print_xml_writer_core(xml, constrained,
"Array");
1082 fwrite(xml.get_doc(),
sizeof(
char), xml.get_doc_size(), out);
1092 print_xml_writer_core(xml, constrained,
"Array");
1093 out << xml.get_doc();
1103 print_xml_writer_core(xml, constrained,
"Map");
1104 fwrite(xml.get_doc(),
sizeof(
char), xml.get_doc_size(), out);
1114 print_xml_writer_core(xml, constrained,
"Map");
1115 out << xml.get_doc();
1125 print_xml_writer_core(xml, constrained, tag);
1126 fwrite(xml.get_doc(),
sizeof(
char), xml.get_doc_size(), out);
1136 print_xml_writer_core(xml, constrained, tag);
1137 out << xml.get_doc();
1143 print_xml_writer_core(xml, constrained,
"Array");
1147 Array::print_as_map_xml_writer(
XMLWriter &xml,
bool constrained)
1149 print_xml_writer_core(xml, constrained,
"Map");
1152 class PrintArrayDimXMLWriter :
public unary_function<Array::dimension&, void>
1157 PrintArrayDimXMLWriter(XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) {}
1159 void operator()(Array::dimension &d)
1161 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"dimension") < 0)
1162 throw InternalErr(__FILE__, __LINE__,
"Could not write dimension element");
1164 if (!d.name.empty())
1165 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)d.name.c_str()) < 0)
1166 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1169 size << (d_constrained ? d.c_size : d.size);
1170 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size", (
const xmlChar*)size.str().c_str()) < 0)
1171 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1173 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1174 throw InternalErr(__FILE__, __LINE__,
"Could not end dimension element");
1179 Array::print_xml_writer_core(XMLWriter &xml,
bool constrained,
string tag)
1181 if (constrained && !
send_p())
1184 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)tag.c_str()) < 0)
1185 throw InternalErr(__FILE__, __LINE__,
"Could not write " + tag +
" element");
1187 if (!
name().empty())
1188 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
1189 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1194 string tmp_name = btp->name();
1196 btp->print_xml_writer(xml, constrained);
1197 btp->set_name(tmp_name);
1199 for_each(
dim_begin(),
dim_end(), PrintArrayDimXMLWriter(xml, constrained));
1201 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1202 throw InternalErr(__FILE__, __LINE__,
"Could not end " + tag +
" element");
1218 unsigned int shape[])
1221 unsigned int i =
print_array(oss, index, dims, shape);
1222 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
1238 unsigned int Array::print_array(ostream &out,
unsigned int index,
unsigned int dims,
unsigned int shape[])
1244 if (shape[0] >= 1) {
1245 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1270 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1271 index =
print_array(out, index, dims - 1, shape + 1);
1275 index =
print_array(out, index, dims - 1, shape + 1);
1289 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
1306 unsigned int *shape =
new unsigned int[
dimensions(
true)];
1307 unsigned int index = 0;
1308 for (
Dim_iter i = _shape.begin(); i != _shape.end() && index <
dimensions(
true); ++i)
1313 delete [] shape; shape = 0;
1335 msg =
"An array variable must have dimensions";
1351 strm << DapIndent::LMarg <<
"Array::dump - ("
1352 << (
void *)
this <<
")" << endl ;
1353 DapIndent::Indent() ;
1355 strm << DapIndent::LMarg <<
"shape:" << endl ;
1356 DapIndent::Indent() ;
1359 unsigned int dim_num = 0 ;
1360 for (; i != ie; i++) {
1361 strm << DapIndent::LMarg <<
"dimension " << dim_num++ <<
":"
1363 DapIndent::Indent() ;
1364 strm << DapIndent::LMarg <<
"name: " << (*i).name << endl ;
1365 strm << DapIndent::LMarg <<
"size: " << (*i).size << endl ;
1366 strm << DapIndent::LMarg <<
"start: " << (*i).start << endl ;
1367 strm << DapIndent::LMarg <<
"stop: " << (*i).stop << endl ;
1368 strm << DapIndent::LMarg <<
"stride: " << (*i).stride << endl ;
1369 strm << DapIndent::LMarg <<
"constrained size: " << (*i).c_size
1371 DapIndent::UnIndent() ;
1373 DapIndent::UnIndent() ;
1374 DapIndent::UnIndent() ;