47 #include "D4Attributes.h" 49 #include "D4Dimensions.h" 52 #include "D4EnumDefs.h" 54 #include "XMLWriter.h" 58 #include "InternalErr.h" 60 #include "DapIndent.h" 66 Array::dimension::dimension(D4Dimension *d) : dim(d), use_sdim_for_slice(true)
78 Array::_duplicate(
const Array &a)
84 d_maps =
new D4Maps(*(a.d_maps));
108 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
112 length *= (*i).c_size > 0 ? (*i).c_size : 1;
114 length *= (*i).c_size;
139 :
Vector(n, 0, dods_array_c, is_dap4), d_maps(0)
158 :
Vector(n, d, 0, dods_array_c, is_dap4), d_maps(0)
178 return new Array(*
this);
182 Array::operator=(
const Array &rhs)
187 dynamic_cast<Vector &
>(*this) = rhs;
197 DBG(cerr << __func__ <<
"() - BEGIN (array:" <<
name() <<
")" << endl;);
202 DBG(cerr << __func__ <<
"() - Already DAP4 type: Just making a copy and adding to container. " << endl;);
204 DBG(cerr << __func__ <<
"() - END (Already DAP4 type)" << endl;);
212 for (
Array::Dim_iter dap2_dim = dest->dim_begin(), e = dest->dim_end(); dap2_dim != e; ++dap2_dim) {
213 if (!(*dap2_dim).name.empty()) {
214 DBG(cerr << __func__ <<
"() - Processing the array dimension '" << (*dap2_dim).name <<
"'" << endl;);
217 D4Dimension *d4_dim = root_dims->find_dim((*dap2_dim).name);
219 d4_dim =
new D4Dimension((*dap2_dim).name, (*dap2_dim).size);
220 root_dims->add_dim_nocopy(d4_dim);
221 DBG(cerr << __func__ <<
"() -" <<
222 " Added NEW D4Dimension '"<< d4_dim->name() <<
"' (" <<
223 (
void *)d4_dim <<
") to root->dims()"<< endl;);
226 DBG(cerr << __func__ <<
"() -" <<
227 " Using Existing D4Dimension '"<< d4_dim->name() <<
"' (" <<
228 (
void *)d4_dim <<
")"<< endl;);
230 if (d4_dim->size() != (
unsigned long) (*dap2_dim).size) {
242 d4_dim =
new D4Dimension((*dap2_dim).name +
"_" +
name(), (*dap2_dim).size);
243 DBG(cerr << __func__ <<
"() -" <<
244 " Utilizing Name/Size Conflict Naming Artifice. name'"<< d4_dim->name() <<
"' (" <<
245 (
void *)d4_dim <<
")"<< endl;);
246 root_dims->add_dim_nocopy(d4_dim);
251 (*dap2_dim).dim = d4_dim;
258 dest->set_is_dap4(
true);
260 DBG(cerr << __func__ <<
"() - END (array:" <<
name() <<
")" << endl;);
263 bool Array::is_dap2_grid(){
264 bool is_grid =
false;
266 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' is DAP4 object!" << endl;)
267 D4Maps *d4_maps = this->maps();
268 is_grid = d4_maps->size();
270 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' has D4Maps." << endl;)
272 D4Maps::D4MapsIter i = d4_maps->map_begin();
273 D4Maps::D4MapsIter e = d4_maps->map_end();
275 DBG( cerr << __func__ <<
"() - Map '"<< (*i)->array()->name() <<
" has " << (*i)->array()->_shape.size() <<
" dimension(s)." << endl;)
276 if((*i)->array()->_shape.size() > 1){
286 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' has no D4Maps." << endl;)
289 DBG( cerr << __func__ <<
"() - is_grid: "<< (is_grid?
"true":
"false") << endl;)
308 std::vector<BaseType *> *
310 DBG(cerr << __func__ <<
"() - BEGIN Array '"<<
name() <<
"'" << endl;);
318 DBG(cerr << __func__ <<
"() - Array '"<<
name() <<
"' is dap2 Grid!" << endl;);
322 g->set_array(grid_array);
333 g->set_attr_table(at);
336 D4Maps *d4_maps = this->maps();
337 vector<BaseType *> dropped_maps;
338 D4Maps::D4MapsIter miter = d4_maps->map_begin();
339 D4Maps::D4MapsIter end = d4_maps->map_end();
340 for( ; miter!=end; miter++){
341 D4Map *d4_map = (*miter);
342 Array *d4_map_array =
const_cast<Array*
>(d4_map->array());
343 vector<BaseType *> *d2_result = d4_map_array->
transform_to_dap2(&(g->get_attr_table()));
345 if(d2_result->size()>1)
346 throw Error(internal_error,
string(__func__)+
"() - ERROR: D4Map Array conversion resulted in multiple DAP2 objects.");
349 Array *d2_map_array =
dynamic_cast<Array *
>((*d2_result)[0]);
352 throw Error(internal_error,
string(__func__)+
"() - ERROR: DAP2 array from D4Map Array conversion has more than 1 dimension.");
354 g->add_map(d2_map_array,
false);
356 DBG( cerr << __func__ <<
"() - " <<
357 "DAS For Grid Map '" << d2_map_array->
name() <<
"':" << endl;
361 throw Error(internal_error,
string(__func__)+
"() - Unable to interpret returned DAP2 content.");
366 dropped_maps.push_back(d4_map_array);
371 if(!dropped_maps.empty()){
373 AttrTable *dv_table = Constructor::make_dropped_vars_attr_table(&dropped_maps);
374 dest->get_attr_table().append_container(dv_table,dv_table->
get_name());
379 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' is not a Grid!" << endl);
380 BaseType *proto = this->prototype();
381 switch(proto->
type()){
398 dest->set_attr_table(*attrs);
399 dest->set_is_dap4(
false);
401 DBG( cerr << __func__ <<
"() - " <<
402 "DAS for new Array '" << dest->name() <<
"':" << endl;
416 vector<BaseType *> *result;
418 result =
new vector<BaseType *>();
419 result->push_back(dest);
424 DBG( cerr << __func__ <<
"() - END Array '"<<
name() <<
"'" << endl;);
442 std::vector<dimension>::iterator i = _shape.begin(), e = _shape.end();
445 while (old_i != old_e) {
446 if ((*i).dim == *old_i) {
447 (*i).dim = new_dims->find_dim((*old_i)->name());
486 if (v && v->
type() == dods_array_c) {
508 if (v && v->
type() == dods_array_c) {
510 Vector::add_var_nocopy(a.
var());
519 Vector::add_var_nocopy(v);
562 _shape.insert(_shape.begin(), d);
572 _shape.insert(_shape.begin(), d);
596 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
598 (*i).stop = (*i).size - 1;
600 (*i).c_size = (*i).size;
624 static const char *array_sss = \
625 "Invalid constraint parameters: At least one of the start, stride or stop \n\ 626 specified do not match the array variable.";
662 if (start >= d.
size || stop >= d.
size || stride > d.
size || stride <= 0)
663 throw Error(malformed_expr, array_sss);
665 if (((stop - start) / stride + 1) > d.
size)
666 throw Error(malformed_expr, array_sss);
672 d.
c_size = (stop - start) / stride + 1;
674 DBG(cerr <<
"add_constraint: c_size = " << d.
c_size << endl);
686 if (dim->constrained())
687 add_constraint(i, dim->c_start(), dim->c_stride(), dim->c_stop());
689 dim->set_used_by_projected_var(
true);
700 return _shape.begin() ;
707 return _shape.end() ;
723 return _shape.size();
748 if (!_shape.empty()) {
779 return (!_shape.empty()) ? (*i).start : 0;
803 return (!_shape.empty()) ? (*i).stop : 0;
828 return (!_shape.empty()) ? (*i).stride : 0;
851 "*This* array has no dimensions.");
858 return (!_shape.empty()) ? (*i).dim : 0;
864 if (!d_maps) d_maps =
new D4Maps(
this);
886 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
889 return length *
var()->
width(
false);
894 class PrintD4ArrayDimXMLWriter:
public unary_function<Array::dimension&, void> {
901 PrintD4ArrayDimXMLWriter(XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) { }
903 void operator()(Array::dimension &d)
909 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"Dim") < 0)
910 throw InternalErr(__FILE__, __LINE__,
"Could not write Dim element");
912 string name = (d.dim) ? d.dim->fully_qualified_name() : d.name;
915 if (!d_constrained && !name.empty()) {
916 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
917 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
919 else if (d.use_sdim_for_slice) {
920 assert(!name.empty());
921 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
922 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
926 size << (d_constrained ? d.c_size : d.size);
927 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size",
928 (
const xmlChar*) size.str().c_str()) < 0)
929 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
932 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
933 throw InternalErr(__FILE__, __LINE__,
"Could not end Dim element");
937 class PrintD4ConstructorVarXMLWriter:
public unary_function<BaseType*, void> {
941 PrintD4ConstructorVarXMLWriter(XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) { }
945 btp->print_dap4(xml, d_constrained);
949 class PrintD4MapXMLWriter:
public unary_function<D4Map*, void> {
953 PrintD4MapXMLWriter(XMLWriter &xml) : xml(xml) { }
955 void operator()(D4Map *m)
969 if (constrained && !
send_p())
return;
971 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
var()->
type_name().c_str()) < 0)
975 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
976 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
979 if (
var()->
type() == dods_enum_c) {
981 string path = e->enumeration()->name();
982 if (e->enumeration()->parent()) {
984 path =
static_cast<D4Group*
>(e->enumeration()->parent()->parent())->
FQN() + path;
986 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"enum", (
const xmlChar*)path.c_str()) < 0)
987 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for enum");
992 for_each(c.
var_begin(), c.
var_end(), PrintD4ConstructorVarXMLWriter(xml, constrained));
997 for_each(
dim_begin(),
dim_end(), PrintD4ArrayDimXMLWriter(xml, constrained));
1001 for_each(maps()->map_begin(), maps()->map_end(), PrintD4MapXMLWriter(xml));
1003 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1026 bool constraint_info,
bool constrained)
1029 print_decl(oss, space, print_semi, constraint_info, constrained);
1030 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
1050 void Array::print_decl(ostream &out,
string space,
bool print_semi,
bool constraint_info,
bool constrained)
1052 if (constrained && !
send_p())
return;
1055 var()->
print_decl(out, space,
false, constraint_info, constrained);
1057 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
1059 if ((*i).name !=
"") {
1060 out <<
id2www((*i).name) <<
" = ";
1063 out << (*i).c_size <<
"]";
1066 out << (*i).size <<
"]";
1082 print_xml_writer_core(xml, constrained,
"Array");
1083 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
1093 print_xml_writer_core(xml, constrained,
"Array");
1094 out << xml.get_doc();
1104 print_xml_writer_core(xml, constrained,
"Map");
1105 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
1115 print_xml_writer_core(xml, constrained,
"Map");
1116 out << xml.get_doc();
1126 print_xml_writer_core(xml, constrained, tag);
1127 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
1137 print_xml_writer_core(xml, constrained, tag);
1138 out << xml.get_doc();
1144 print_xml_writer_core(xml, constrained,
"Array");
1148 Array::print_as_map_xml_writer(
XMLWriter &xml,
bool constrained)
1150 print_xml_writer_core(xml, constrained,
"Map");
1153 class PrintArrayDimXMLWriter :
public unary_function<Array::dimension&, void>
1158 PrintArrayDimXMLWriter(
XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) {}
1162 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"dimension") < 0)
1163 throw InternalErr(__FILE__, __LINE__,
"Could not write dimension element");
1165 if (!d.
name.empty())
1166 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)d.
name.c_str()) < 0)
1167 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1171 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size", (
const xmlChar*)size.str().c_str()) < 0)
1172 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1174 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1175 throw InternalErr(__FILE__, __LINE__,
"Could not end dimension element");
1180 Array::print_xml_writer_core(
XMLWriter &xml,
bool constrained,
string tag)
1182 if (constrained && !
send_p())
1185 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)tag.c_str()) < 0)
1186 throw InternalErr(__FILE__, __LINE__,
"Could not write " + tag +
" element");
1188 if (!
name().empty())
1189 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
1190 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1195 string tmp_name = btp->
name();
1200 for_each(
dim_begin(),
dim_end(), PrintArrayDimXMLWriter(xml, constrained));
1202 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1203 throw InternalErr(__FILE__, __LINE__,
"Could not end " + tag +
" element");
1219 unsigned int shape[])
1222 unsigned int i =
print_array(oss, index, dims, shape);
1223 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
1239 unsigned int Array::print_array(ostream &out,
unsigned int index,
unsigned int dims,
unsigned int shape[])
1245 if (shape[0] >= 1) {
1246 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1271 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1272 index =
print_array(out, index, dims - 1, shape + 1);
1276 index =
print_array(out, index, dims - 1, shape + 1);
1290 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
1307 unsigned int *shape =
new unsigned int[
dimensions(
true)];
1308 unsigned int index = 0;
1309 for (
Dim_iter i = _shape.begin(); i != _shape.end() && index <
dimensions(
true); ++i)
1314 delete [] shape; shape = 0;
1336 msg =
"An array variable must have dimensions";
1352 strm << DapIndent::LMarg <<
"Array::dump - (" 1353 << (
void *)
this <<
")" << endl ;
1354 DapIndent::Indent() ;
1356 strm << DapIndent::LMarg <<
"shape:" << endl ;
1357 DapIndent::Indent() ;
1360 unsigned int dim_num = 0 ;
1361 for (; i != ie; i++) {
1362 strm << DapIndent::LMarg <<
"dimension " << dim_num++ <<
":" 1364 DapIndent::Indent() ;
1365 strm << DapIndent::LMarg <<
"name: " << (*i).name << endl ;
1366 strm << DapIndent::LMarg <<
"size: " << (*i).size << endl ;
1367 strm << DapIndent::LMarg <<
"start: " << (*i).start << endl ;
1368 strm << DapIndent::LMarg <<
"stop: " << (*i).stop << endl ;
1369 strm << DapIndent::LMarg <<
"stride: " << (*i).stride << endl ;
1370 strm << DapIndent::LMarg <<
"constrained size: " << (*i).c_size
1372 DapIndent::UnIndent() ;
1374 DapIndent::UnIndent() ;
1375 DapIndent::UnIndent() ;
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
virtual void reset_constraint()
Reset constraint to select entire array.
virtual void add_constraint(Dim_iter i, int start, int stride, int stop)
Adds a constraint to an Array dimension.
virtual string name() const
Returns the name of the class instance.
virtual bool check_semantics(string &msg, bool all=false)
Check semantic features of the Array.
virtual void print_xml_core(FILE *out, string space, bool constrained, string tag)
vector< D4Dimension * >::iterator D4DimensionsIter
Iterator used for D4Dimensions.
virtual void dump(ostream &strm) const
dumps information about this object
virtual void print_decl(FILE *out, string space=" ", bool print_semi=true, bool constraint_info=false, bool constrained=false)
Print an ASCII representation of the variable structure.
Array(const string &n, BaseType *v, bool is_dap4=false)
Array constructor.
AttrTable * get_AttrTable(const std::string name)
copy attributes from DAP4 to DAP2
virtual unsigned int dimensions(bool constrained=false)
Return the total number of dimensions in the array.
Part
Names the parts of multi-section constructor data types.
void add_var(BaseType *v, Part p=nil)
Add the BaseType pointer to this constructor type instance.
Contains the attributes for a dataset.
virtual void set_name(const string &n)
Sets the name of the class instance.
int stop
The constraint end index.
Holds a one-dimensional collection of DAP2 data types.
virtual unsigned int width(bool constrained=false) const
Returns the width of the data, in bytes.
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
virtual string get_name() const
Get the name of this attribute table.
std::vector< dimension >::const_iterator Dim_citer
bool use_sdim_for_slice
Used to control printing the DMR in data responses.
int start
The constraint start index.
BaseType(const string &n, const Type &t, bool is_dap4=false)
The BaseType constructor.
virtual void add_var(BaseType *v, Part p=nil)
Add the BaseType pointer to this constructor type instance.
D4DimensionsIter dim_end()
Get an iterator to the end of the dimensions.
void print_xml_writer(XMLWriter &xml)
virtual void add_var_nocopy(BaseType *bt, Part part=nil)
virtual void print(FILE *out, string pad=" ", bool dereference=false)
Prints the attribute table.
void append_dim(int size, const string &name="")
Add a dimension of a given size.
virtual void update_length(int size=0)
D4DimensionsIter dim_begin()
Get an iterator to the start of the dimensions.
top level DAP object to house generic methods
A class for software fault reporting.
virtual std::string FQN() const
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
virtual void print_as_map_xml(ostream &out, string space=" ", bool constrained=false)
virtual std::vector< BaseType * > * transform_to_dap2(AttrTable *parent_attr_table)
Transforms this instance of a D4Array into the corresponding DAP2 object.
Holds a DAP4 enumeration.
virtual int dimension_size(Dim_iter i, bool constrained=false)
Returns the size of the dimension.
virtual void print_val(FILE *out, string space="", bool print_decl_p=true)
Prints the value of the variable.
virtual bool is_constructor_type() const
Returns true if the instance is a constructor (i.e., Structure, Sequence or Grid) type variable...
virtual AttrTable * get_attr_table(const string &name)
Get an attribute container.
virtual Type type() const
Returns the type of the class instance.
std::vector< dimension >::iterator Dim_iter
virtual string dimension_name(Dim_iter i)
Returns the name of the specified dimension.
virtual BaseType * ptr_duplicate()
virtual int dimension_stride(Dim_iter i, bool constrained=false)
Returns the stride value of the constraint.
Holds the Grid data type.
int stride
The constraint stride.
virtual void print_decl(ostream &out, string space=" ", bool print_semi=true, bool constraint_info=false, bool constrained=false)
Prints a DDS entry for the Array.
int c_size
Size of dimension once constrained.
virtual D4Attributes * attributes()
void prepend_dim(int size, const string &name="")
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
string www2id(const string &in, const string &escape, const string &except)
virtual int dimension_stop(Dim_iter i, bool constrained=false)
Return the stop index of the constraint.
virtual int dimension_start(Dim_iter i, bool constrained=false)
Return the start index of a dimension.
virtual AttrTable & get_attr_table()
virtual void print_dap4(XMLWriter &xml, bool constrained=false)
Print the DAP4 representation of an array.
virtual ~Array()
The Array destructor.
int size
The unconstrained dimension size.
string name
The name of this dimension.
The basic data type for the DODS DAP types.
virtual string type_name() const
Returns the type of the class instance as a string.
virtual void set_attr_table(const AttrTable &at)
virtual int length() const
virtual void set_length(int l)
A class for error processing.
virtual void set_name(const string &n)
Set the name of this attribute table.
unsigned int print_array(FILE *out, unsigned int index, unsigned int dims, unsigned int shape[])
Print the value given the current constraint.
A multidimensional array of identical data types.
virtual void print_val(ostream &out, string space="", bool print_decl_p=true)
Prints the value of the variable.
virtual unsigned int width(bool constrained=false) const
How many bytes does this use Return the number of bytes of storage this variable uses. For scalar types, this is pretty simple (an int32 uses 4 bytes, etc.). For arrays and Constructors, it is a bit more complex. Note that a scalar String variable uses sizeof(String*) bytes, not the length of the string. In other words, the value returned is independent of the type. Also note width() of a String array returns the number of elements in the array times sizeof(String*). That is, each different array size is a different data type.
virtual bool send_p()
Should this variable be sent?
virtual void transform_to_dap4(D4Group *root, Constructor *container)
DAP2 to DAP4 transform.
virtual void dump(ostream &strm) const
dumps information about this object
string id2www(string in, const string &allowable)
D4Dimensions * dims()
Get the dimensions defined for this Group.
virtual void clear_constraint()
Clears the projection; add each projected dimension explicitly using add_constraint.
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.