46 #include "D4Attributes.h" 48 #include "D4Dimensions.h" 51 #include "D4EnumDefs.h" 53 #include "XMLWriter.h" 57 #include "InternalErr.h" 59 #include "DapIndent.h" 65 Array::dimension::dimension(D4Dimension *d) :
66 dim(d), use_sdim_for_slice(true)
77 void Array::_duplicate(
const Array &a)
83 d_maps =
new D4Maps(*(a.d_maps));
106 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
110 length *= (*i).c_size > 0 ? (*i).c_size : 1;
112 length *= (*i).c_size;
137 Vector(n, 0, dods_array_c, is_dap4), d_maps(0)
156 Vector(n, d, 0, dods_array_c, is_dap4), d_maps(0)
177 return new Array(*
this);
181 Array::operator=(
const Array &rhs)
183 if (
this == &rhs)
return *
this;
185 dynamic_cast<Vector &
>(*this) = rhs;
208 if (!(*dap2_dim).name.empty()) {
211 D4Dimension *d4_dim = root_dims->find_dim((*dap2_dim).name);
213 d4_dim =
new D4Dimension((*dap2_dim).name, (*dap2_dim).size);
217 DBG(cerr << __func__ <<
"() -" <<
218 " Using Existing D4Dimension '"<< d4_dim->name() <<
"' (" <<
219 (
void *)d4_dim <<
")"<< endl);;
221 if (d4_dim->size() != (
unsigned long) (*dap2_dim).size) {
233 d4_dim =
new D4Dimension((*dap2_dim).name +
"_" +
name(), (*dap2_dim).size);
234 DBG(cerr << __func__ <<
"() -" <<
235 " Utilizing Name/Size Conflict Naming Artifice. name'"<< d4_dim->name() <<
"' (" <<
236 (
void *)d4_dim <<
")"<< endl);;
242 (*dap2_dim).dim = d4_dim;
249 dest->set_is_dap4(
true);
251 DBG(cerr << __func__ <<
"() - END (array:" <<
name() <<
")" << endl);;
254 bool Array::is_dap2_grid()
256 bool is_grid =
false;
257 if (this->is_dap4()) {
258 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' is DAP4 object!" << endl);
259 D4Maps *d4_maps = this->maps();
260 is_grid = d4_maps->size();
262 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' has D4Maps." << endl);
264 D4Maps::D4MapsIter i = d4_maps->map_begin();
265 D4Maps::D4MapsIter e = d4_maps->map_end();
267 DBG( cerr << __func__ <<
"() - Map '"<< (*i)->array()->name() <<
" has " << (*i)->array()->_shape.size() <<
" dimension(s)." << endl);
268 if ((*i)->array()->_shape.size() > 1) {
278 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' has no D4Maps." << endl);
282 DBG( cerr << __func__ <<
"() - is_grid: "<< (is_grid?
"true":
"false") << endl);
301 std::vector<BaseType *> *
304 DBG(cerr << __func__ <<
"() - BEGIN Array '"<<
name() <<
"'" << endl);;
314 if (is_dap2_grid()) {
316 DBG(cerr << __func__ <<
"() - Array '"<<
name() <<
"' is dap2 Grid!" << endl);;
326 D4Maps *d4_maps = this->maps();
327 vector<BaseType *> dropped_maps;
328 D4Maps::D4MapsIter miter = d4_maps->map_begin();
329 D4Maps::D4MapsIter end = d4_maps->map_end();
330 for (; miter != end; miter++) {
331 D4Map *d4_map = (*miter);
332 Array *d4_map_array =
const_cast<Array*
>(d4_map->array());
335 if (d2_result->size() > 1)
336 throw Error(internal_error,
"D4Map Array conversion resulted in multiple DAP2 objects.");
339 Array *d2_map_array =
dynamic_cast<Array *
>((*d2_result)[0]);
342 throw Error(internal_error,
"DAP2 array from D4Map Array conversion has more than 1 dimension.");
344 g->
add_map(d2_map_array,
false);
346 DBG( cerr << __func__ <<
"() - " <<
347 "DAS For Grid Map '" << d2_map_array->
name() <<
"':" << endl;
351 throw Error(internal_error,
"Unable to interpret returned DAP2 content.");
356 dropped_maps.push_back(d4_map_array);
361 if (!dropped_maps.empty()) {
363 AttrTable *dv_table = Constructor::make_dropped_vars_attr_table(&dropped_maps);
368 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' is not a Grid!" << endl);
371 switch (proto->
type()) {
400 dest->set_is_dap4(
false);
406 vector<BaseType *> *result;
408 result =
new vector<BaseType *>();
409 result->push_back(dest);
415 DBG( cerr << __func__ <<
"() - END Array '"<<
name() <<
"'" << endl);;
432 std::vector<dimension>::iterator i = _shape.begin(), e = _shape.end();
435 while (old_i != old_e) {
436 if ((*i).dim == *old_i) {
437 (*i).dim = new_dims->find_dim((*old_i)->name());
475 if (v && v->
type() == dods_array_c) {
496 if (v && v->
type() == dods_array_c) {
498 Vector::add_var_nocopy(a.
var());
507 Vector::add_var_nocopy(v);
547 _shape.insert(_shape.begin(), d);
556 _shape.insert(_shape.begin(), d);
576 std::vector<dimension>::iterator i = _shape.begin(), e = _shape.end();
579 if (d.
name == oldName) {
580 DBG(cerr <<
"Old name = " << d.
name <<
" newName = " << newName << endl);
597 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
599 (*i).stop = (*i).size - 1;
601 (*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.";
653 if (stop == -1) stop = d.
size - 1;
659 if (start >= d.
size || stop >= d.
size || stride > d.
size || stride <= 0)
throw Error(malformed_expr, array_sss);
661 if (((stop - start) / stride + 1) > d.
size)
throw Error(malformed_expr, array_sss);
667 d.
c_size = (stop - start) / stride + 1;
669 DBG(cerr <<
"add_constraint: c_size = " << d.
c_size << endl);
680 if (dim->constrained())
add_constraint(i, dim->c_start(), dim->c_stride(), dim->c_stop());
682 dim->set_used_by_projected_var(
true);
692 return _shape.begin();
713 return _shape.size();
737 if (!_shape.empty()) {
767 return (!_shape.empty()) ? (*i).start : 0;
790 return (!_shape.empty()) ? (*i).stop : 0;
814 return (!_shape.empty()) ? (*i).stride : 0;
834 if (_shape.empty())
throw InternalErr(__FILE__, __LINE__,
"*This* array has no dimensions.");
841 return (!_shape.empty()) ? (*i).dim : 0;
847 if (!d_maps) d_maps =
new D4Maps(
this);
869 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
872 return length *
var()->
width(
false);
877 class PrintD4ArrayDimXMLWriter:
public unary_function<Array::dimension&, void> {
884 PrintD4ArrayDimXMLWriter(XMLWriter &xml,
bool c) :
885 xml(xml), d_constrained(c)
889 void operator()(Array::dimension &d)
895 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"Dim") < 0)
896 throw InternalErr(__FILE__, __LINE__,
"Could not write Dim element");
898 string name = (d.dim) ? d.dim->fully_qualified_name() : d.name;
901 if (!d_constrained && !name.empty()) {
902 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
903 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
905 else if (d.use_sdim_for_slice) {
906 assert(!name.empty());
907 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
908 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
912 size << (d_constrained ? d.c_size : d.size);
913 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size",
914 (
const xmlChar*) size.str().c_str()) < 0)
915 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
918 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
919 throw InternalErr(__FILE__, __LINE__,
"Could not end Dim element");
923 class PrintD4ConstructorVarXMLWriter:
public unary_function<BaseType*, void> {
927 PrintD4ConstructorVarXMLWriter(XMLWriter &xml,
bool c) :
928 xml(xml), d_constrained(c)
934 btp->print_dap4(xml, d_constrained);
938 class PrintD4MapXMLWriter:
public unary_function<D4Map*, void> {
942 PrintD4MapXMLWriter(XMLWriter &xml) :
947 void operator()(D4Map *m)
960 if (constrained && !
send_p())
return;
962 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
var()->
type_name().c_str()) < 0)
966 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
967 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
970 if (
var()->
type() == dods_enum_c) {
972 string path = e->enumeration()->name();
973 if (e->enumeration()->parent()) {
975 path =
static_cast<D4Group*
>(e->enumeration()->parent()->parent())->
FQN() + path;
977 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"enum", (
const xmlChar*) path.c_str()) < 0)
978 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for enum");
983 for_each(c.
var_begin(), c.
var_end(), PrintD4ConstructorVarXMLWriter(xml, constrained));
988 for_each(
dim_begin(),
dim_end(), PrintD4ArrayDimXMLWriter(xml, constrained));
992 for_each(maps()->map_begin(), maps()->map_end(), PrintD4MapXMLWriter(xml));
994 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1015 void Array::print_decl(FILE *out,
string space,
bool print_semi,
bool constraint_info,
bool constrained)
1018 print_decl(oss, space, print_semi, constraint_info, constrained);
1019 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
1039 void Array::print_decl(ostream &out,
string space,
bool print_semi,
bool constraint_info,
bool constrained)
1041 if (constrained && !
send_p())
return;
1044 var()->
print_decl(out, space,
false, constraint_info, constrained);
1046 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
1048 if ((*i).name !=
"") {
1049 out <<
id2www((*i).name) <<
" = ";
1052 out << (*i).c_size <<
"]";
1055 out << (*i).size <<
"]";
1070 print_xml_writer_core(xml, constrained,
"Array");
1071 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
1080 print_xml_writer_core(xml, constrained,
"Array");
1081 out << xml.get_doc();
1090 print_xml_writer_core(xml, constrained,
"Map");
1091 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
1100 print_xml_writer_core(xml, constrained,
"Map");
1101 out << xml.get_doc();
1110 print_xml_writer_core(xml, constrained, tag);
1111 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
1120 print_xml_writer_core(xml, constrained, tag);
1121 out << xml.get_doc();
1126 print_xml_writer_core(xml, constrained,
"Array");
1129 void Array::print_as_map_xml_writer(
XMLWriter &xml,
bool constrained)
1131 print_xml_writer_core(xml, constrained,
"Map");
1134 class PrintArrayDimXMLWriter:
public unary_function<Array::dimension&, void> {
1138 PrintArrayDimXMLWriter(
XMLWriter &xml,
bool c) :
1139 xml(xml), d_constrained(c)
1145 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"dimension") < 0)
1146 throw InternalErr(__FILE__, __LINE__,
"Could not write dimension element");
1148 if (!d.
name.empty())
1149 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) d.
name.c_str())
1150 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1154 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size", (
const xmlChar*) size.str().c_str())
1155 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1157 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1158 throw InternalErr(__FILE__, __LINE__,
"Could not end dimension element");
1162 void Array::print_xml_writer_core(
XMLWriter &xml,
bool constrained,
string tag)
1164 if (constrained && !
send_p())
return;
1166 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*) tag.c_str()) < 0)
1167 throw InternalErr(__FILE__, __LINE__,
"Could not write " + tag +
" element");
1169 if (!
name().empty())
1170 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
1171 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1176 string tmp_name = btp->
name();
1181 for_each(
dim_begin(),
dim_end(), PrintArrayDimXMLWriter(xml, constrained));
1183 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1184 throw InternalErr(__FILE__, __LINE__,
"Could not end " + tag +
" element");
1201 unsigned int i =
print_array(oss, index, dims, shape);
1202 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
1218 unsigned int Array::print_array(ostream &out,
unsigned int index,
unsigned int dims,
unsigned int shape[])
1224 if (shape[0] >= 1) {
1225 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1250 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1251 index =
print_array(out, index, dims - 1, shape + 1);
1255 index =
print_array(out, index, dims - 1, shape + 1);
1268 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
1284 unsigned int *shape =
new unsigned int[
dimensions(
true)];
1285 unsigned int index = 0;
1286 for (
Dim_iter i = _shape.begin(); i != _shape.end() && index <
dimensions(
true); ++i)
1312 if (!sem) msg =
"An array variable must have dimensions";
1327 strm << DapIndent::LMarg <<
"Array::dump - (" << (
void *)
this <<
")" << endl;
1328 DapIndent::Indent();
1330 strm << DapIndent::LMarg <<
"shape:" << endl;
1331 DapIndent::Indent();
1334 unsigned int dim_num = 0;
1335 for (; i != ie; i++) {
1336 strm << DapIndent::LMarg <<
"dimension " << dim_num++ <<
":" << endl;
1337 DapIndent::Indent();
1338 strm << DapIndent::LMarg <<
"name: " << (*i).name << endl;
1339 strm << DapIndent::LMarg <<
"size: " << (*i).size << endl;
1340 strm << DapIndent::LMarg <<
"start: " << (*i).start << endl;
1341 strm << DapIndent::LMarg <<
"stop: " << (*i).stop << endl;
1342 strm << DapIndent::LMarg <<
"stride: " << (*i).stride << endl;
1343 strm << DapIndent::LMarg <<
"constrained size: " << (*i).c_size << endl;
1344 DapIndent::UnIndent();
1346 DapIndent::UnIndent();
1347 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.
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
void transform_attrs_to_dap2(AttrTable *d2_attr_table)
Copy the attributes from this D4Attributes object to a DAP2 AttrTable.
virtual void set_array(Array *p_new_arr)
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...
void add_dim_nocopy(D4Dimension *dim)
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
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()
virtual Array * add_map(Array *p_new_map, bool add_copy)
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 int length() const
void rename_dim(const string &oldName="", const string &newName="")
Renames dimension.
virtual void set_length(int l)
A class for error processing.
virtual unsigned int get_size() const
Get the number of entries in this attribute table.
virtual void set_name(const string &n)
Set the name of this attribute table.
void transform_to_dap4(AttrTable &at)
copy attributes from DAP2 to DAP4
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 variable use Return the number of bytes of storage this variable uses...
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.