46#include "D4Attributes.h"
48#include "D4Dimensions.h"
51#include "D4EnumDefs.h"
57#include "InternalErr.h"
65Array::dimension::dimension(D4Dimension *d) :
66 dim(d), use_sdim_for_slice(true)
77void Array::_duplicate(
const Array &a)
83 d_maps =
new D4Maps(*(a.d_maps));
102void Array::update_length(
int)
105 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
106 length *= (*i).c_size;
130Array::Array(
const string &n,
BaseType *v,
bool is_dap4 ) :
131 Vector(n, 0, dods_array_c, is_dap4), d_maps(0)
150 Vector(n, d, 0, dods_array_c, is_dap4), d_maps(0)
171 return new Array(*
this);
175Array::operator=(
const Array &rhs)
177 if (
this == &rhs)
return *
this;
178 Vector::operator=(rhs);
199 if (!(*dap2_dim).name.empty()) {
202 D4Dimension *d4_dim = root_dims->find_dim((*dap2_dim).name);
204 d4_dim =
new D4Dimension((*dap2_dim).name, (*dap2_dim).size);
208 DBG(cerr << __func__ <<
"() -" <<
209 " Using Existing D4Dimension '"<< d4_dim->name() <<
"' (" <<
210 (
void *)d4_dim <<
")"<< endl);;
212 if (d4_dim->size() != (
unsigned long) (*dap2_dim).size) {
224 d4_dim =
new D4Dimension((*dap2_dim).name +
"_" +
name(), (*dap2_dim).size);
225 DBG(cerr << __func__ <<
"() -" <<
226 " Utilizing Name/Size Conflict Naming Artifice. name'"<< d4_dim->name() <<
"' (" <<
227 (
void *)d4_dim <<
")"<< endl);;
233 (*dap2_dim).dim = d4_dim;
240 dest->set_is_dap4(
true);
242 DBG(cerr << __func__ <<
"() - END (array:" <<
name() <<
")" << endl);;
245bool Array::is_dap2_grid()
247 bool is_grid =
false;
248 if (this->is_dap4()) {
249 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' is DAP4 object!" << endl);
250 D4Maps *d4_maps = this->maps();
251 is_grid = d4_maps->size();
253 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' has D4Maps." << endl);
255 D4Maps::D4MapsIter i = d4_maps->map_begin();
256 D4Maps::D4MapsIter e = d4_maps->map_end();
258 DBG( cerr << __func__ <<
"() - Map '"<< (*i)->array()->name() <<
" has " << (*i)->array()->_shape.size() <<
" dimension(s)." << endl);
259 if ((*i)->array()->_shape.size() > 1) {
269 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' has no D4Maps." << endl);
273 DBG( cerr << __func__ <<
"() - is_grid: "<< (is_grid?
"true":
"false") << endl);
292std::vector<BaseType *> *
295 DBG(cerr << __func__ <<
"() - BEGIN Array '"<<
name() <<
"'" << endl);;
305 if (is_dap2_grid()) {
307 DBG(cerr << __func__ <<
"() - Array '"<<
name() <<
"' is dap2 Grid!" << endl);;
317 D4Maps *d4_maps = this->maps();
318 vector<BaseType *> dropped_maps;
319 D4Maps::D4MapsIter miter = d4_maps->map_begin();
320 D4Maps::D4MapsIter end = d4_maps->map_end();
321 for (; miter != end; miter++) {
322 D4Map *d4_map = (*miter);
323 Array *d4_map_array =
const_cast<Array*
>(d4_map->array());
326 if (d2_result->size() > 1)
327 throw Error(internal_error,
"D4Map Array conversion resulted in multiple DAP2 objects.");
330 Array *d2_map_array =
dynamic_cast<Array *
>((*d2_result)[0]);
333 throw Error(internal_error,
"DAP2 array from D4Map Array conversion has more than 1 dimension.");
335 g->
add_map(d2_map_array,
false);
337 DBG( cerr << __func__ <<
"() - " <<
338 "DAS For Grid Map '" << d2_map_array->
name() <<
"':" << endl;
342 throw Error(internal_error,
"Unable to interpret returned DAP2 content.");
347 dropped_maps.push_back(d4_map_array);
352 if (!dropped_maps.empty()) {
354 AttrTable *dv_table = Constructor::make_dropped_vars_attr_table(&dropped_maps);
359 DBG( cerr << __func__ <<
"() - Array '"<<
name() <<
"' is not a Grid!" << endl);
362 switch (proto->
type()) {
391 dest->set_is_dap4(
false);
397 vector<BaseType *> *result;
399 result =
new vector<BaseType *>();
400 result->push_back(dest);
406 DBG( cerr << __func__ <<
"() - END Array '"<<
name() <<
"'" << endl);;
423 std::vector<dimension>::iterator i = _shape.begin(), e = _shape.end();
426 while (old_i != old_e) {
427 if ((*i).dim == *old_i) {
428 (*i).dim = new_dims->find_dim((*old_i)->name());
466 if (v && v->
type() == dods_array_c) {
487 if (v && v->
type() == dods_array_c) {
489 Vector::add_var_nocopy(a.
var());
498 Vector::add_var_nocopy(v);
538 _shape.insert(_shape.begin(), d);
547 _shape.insert(_shape.begin(), d);
567 std::vector<dimension>::iterator i = _shape.begin(), e = _shape.end();
570 if (d.
name == oldName) {
571 DBG(cerr <<
"Old name = " << d.
name <<
" newName = " << newName << endl);
588 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
590 (*i).stop = (*i).size - 1;
592 (*i).c_size = (*i).size;
614static const char *array_sss =
615 "Invalid constraint parameters: At least one of the start, stride or stop \n\
616specified do not match the array variable.";
644 if (stop == -1) stop = d.
size - 1;
650 if (start >= d.
size || stop >= d.
size || stride > d.
size || stride <= 0)
throw Error(malformed_expr, array_sss);
652 if (((stop - start) / stride + 1) > d.
size)
throw Error(malformed_expr, array_sss);
658 d.
c_size = (stop - start) / stride + 1;
660 DBG(cerr <<
"add_constraint: c_size = " << d.
c_size << endl);
671 if (dim->constrained())
add_constraint(i, dim->c_start(), dim->c_stride(), dim->c_stop());
673 dim->set_used_by_projected_var(
true);
677 d.use_sdim_for_slice =
true;
683 return _shape.begin();
704 return _shape.size();
728 if (!_shape.empty()) {
758 return (!_shape.empty()) ? (*i).start : 0;
781 return (!_shape.empty()) ? (*i).stop : 0;
805 return (!_shape.empty()) ? (*i).stride : 0;
825 if (_shape.empty())
throw InternalErr(__FILE__, __LINE__,
"*This* array has no dimensions.");
830Array::dimension_D4dim(Dim_iter i)
832 return (!_shape.empty()) ? (*i).dim : 0;
838 if (!d_maps) d_maps =
new D4Maps(
this);
860 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
868class PrintD4ArrayDimXMLWriter:
public unary_function<Array::dimension&, void> {
875 PrintD4ArrayDimXMLWriter(XMLWriter &xml,
bool c) :
876 xml(xml), d_constrained(c)
880 void operator()(Array::dimension &d)
886 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"Dim") < 0)
887 throw InternalErr(__FILE__, __LINE__,
"Could not write Dim element");
889 string name = (d.dim) ? d.dim->fully_qualified_name() : d.name;
892 if (!d_constrained && !name.empty()) {
893 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
894 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
896 else if (d.use_sdim_for_slice) {
897 assert(!name.empty());
898 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
899 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
903 size << (d_constrained ? d.c_size : d.size);
904 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size",
905 (
const xmlChar*) size.str().c_str()) < 0)
906 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
909 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
910 throw InternalErr(__FILE__, __LINE__,
"Could not end Dim element");
914class PrintD4ConstructorVarXMLWriter:
public unary_function<BaseType*, void> {
918 PrintD4ConstructorVarXMLWriter(XMLWriter &xml,
bool c) :
919 xml(xml), d_constrained(c)
923 void operator()(BaseType *btp)
925 btp->print_dap4(xml, d_constrained);
929class PrintD4MapXMLWriter:
public unary_function<D4Map*, void> {
933 PrintD4MapXMLWriter(XMLWriter &xml) :
938 void operator()(D4Map *m)
951 if (constrained && !
send_p())
return;
953 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
var()->
type_name().c_str()) < 0)
957 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
958 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
961 if (
var()->
type() == dods_enum_c) {
963 string path = e->enumeration()->name();
964 if (e->enumeration()->parent()) {
966 path =
static_cast<D4Group*
>(e->enumeration()->parent()->parent())->
FQN() + path;
968 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"enum", (
const xmlChar*) path.c_str()) < 0)
969 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for enum");
974 for_each(c.
var_begin(), c.
var_end(), PrintD4ConstructorVarXMLWriter(xml, constrained));
979 for_each(
dim_begin(),
dim_end(), PrintD4ArrayDimXMLWriter(xml, constrained));
983 for_each(maps()->map_begin(), maps()->map_end(), PrintD4MapXMLWriter(xml));
985 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1006void Array::print_decl(FILE *out,
string space,
bool print_semi,
bool constraint_info,
bool constrained)
1009 print_decl(oss, space, print_semi, constraint_info, constrained);
1010 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
1030void Array::print_decl(ostream &out,
string space,
bool print_semi,
bool constraint_info,
bool constrained)
1032 if (constrained && !
send_p())
return;
1035 var()->
print_decl(out, space,
false, constraint_info, constrained);
1037 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
1039 if ((*i).name !=
"") {
1040 out <<
id2www((*i).name) <<
" = ";
1043 out << (*i).c_size <<
"]";
1046 out << (*i).size <<
"]";
1061 print_xml_writer_core(xml, constrained,
"Array");
1062 fwrite(xml.get_doc(),
sizeof(
char), xml.get_doc_size(), out);
1071 print_xml_writer_core(xml, constrained,
"Array");
1072 out << xml.get_doc();
1081 print_xml_writer_core(xml, constrained,
"Map");
1082 fwrite(xml.get_doc(),
sizeof(
char), xml.get_doc_size(), out);
1091 print_xml_writer_core(xml, constrained,
"Map");
1092 out << xml.get_doc();
1101 print_xml_writer_core(xml, constrained, tag);
1102 fwrite(xml.get_doc(),
sizeof(
char), xml.get_doc_size(), out);
1111 print_xml_writer_core(xml, constrained, tag);
1112 out << xml.get_doc();
1117 print_xml_writer_core(xml, constrained,
"Array");
1120void Array::print_as_map_xml_writer(
XMLWriter &xml,
bool constrained)
1122 print_xml_writer_core(xml, constrained,
"Map");
1125class PrintArrayDimXMLWriter:
public unary_function<Array::dimension&, void> {
1129 PrintArrayDimXMLWriter(XMLWriter &xml,
bool c) :
1130 xml(xml), d_constrained(c)
1134 void operator()(Array::dimension &d)
1136 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"dimension") < 0)
1137 throw InternalErr(__FILE__, __LINE__,
"Could not write dimension element");
1139 if (!d.name.empty())
1140 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) d.name.c_str())
1141 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1144 size << (d_constrained ? d.c_size : d.size);
1145 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size", (
const xmlChar*) size.str().c_str())
1146 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1148 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1149 throw InternalErr(__FILE__, __LINE__,
"Could not end dimension element");
1153void Array::print_xml_writer_core(XMLWriter &xml,
bool constrained,
string tag)
1155 if (constrained && !
send_p())
return;
1157 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*) tag.c_str()) < 0)
1158 throw InternalErr(__FILE__, __LINE__,
"Could not write " + tag +
" element");
1160 if (!
name().empty())
1161 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
1162 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1167 string tmp_name = btp->name();
1169 btp->print_xml_writer(xml, constrained);
1170 btp->set_name(tmp_name);
1172 for_each(
dim_begin(),
dim_end(), PrintArrayDimXMLWriter(xml, constrained));
1174 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1175 throw InternalErr(__FILE__, __LINE__,
"Could not end " + tag +
" element");
1192 unsigned int i =
print_array(oss, index, dims, shape);
1193 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
1209unsigned int Array::print_array(ostream &out,
unsigned int index,
unsigned int dims,
unsigned int shape[])
1215 if (shape[0] >= 1) {
1216 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1241 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1242 index =
print_array(out, index, dims - 1, shape + 1);
1246 index =
print_array(out, index, dims - 1, shape + 1);
1259 fwrite(oss.str().data(),
sizeof(
char), oss.str().length(), out);
1275 unsigned int *shape =
new unsigned int[
dimensions(
true)];
1276 unsigned int index = 0;
1277 for (
Dim_iter i = _shape.begin(); i != _shape.end() && index <
dimensions(
true); ++i)
1303 if (!sem) msg =
"An array variable must have dimensions";
1318 strm << DapIndent::LMarg <<
"Array::dump - (" << (
void *)
this <<
")" << endl;
1319 DapIndent::Indent();
1321 strm << DapIndent::LMarg <<
"shape:" << endl;
1322 DapIndent::Indent();
1325 unsigned int dim_num = 0;
1326 for (; i != ie; i++) {
1327 strm << DapIndent::LMarg <<
"dimension " << dim_num++ <<
":" << endl;
1328 DapIndent::Indent();
1329 strm << DapIndent::LMarg <<
"name: " << (*i).name << endl;
1330 strm << DapIndent::LMarg <<
"size: " << (*i).size << endl;
1331 strm << DapIndent::LMarg <<
"start: " << (*i).start << endl;
1332 strm << DapIndent::LMarg <<
"stop: " << (*i).stop << endl;
1333 strm << DapIndent::LMarg <<
"stride: " << (*i).stride << endl;
1334 strm << DapIndent::LMarg <<
"constrained size: " << (*i).c_size << endl;
1335 DapIndent::UnIndent();
1337 DapIndent::UnIndent();
1338 DapIndent::UnIndent();
A multidimensional array of identical data types.
virtual int dimension_start(Dim_iter i, bool constrained=false)
Return the start index of a dimension.
virtual void clear_constraint()
Clears the projection; add each projected dimension explicitly using add_constraint.
virtual void dump(ostream &strm) const
dumps information about this object
virtual std::vector< BaseType * > * transform_to_dap2(AttrTable *parent_attr_table)
Transforms this instance of a D4Array into the corresponding DAP2 object.
virtual void transform_to_dap4(D4Group *root, Constructor *container)
DAP2 to DAP4 transform.
virtual BaseType * ptr_duplicate()
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
unsigned int print_array(FILE *out, unsigned int index, unsigned int dims, unsigned int shape[])
Print the value given the current constraint.
virtual int dimension_stop(Dim_iter i, bool constrained=false)
Return the stop index of the constraint.
virtual void update_length(int size=0)
virtual void add_constraint(Dim_iter i, int start, int stride, int stop)
Adds a constraint to an Array dimension.
virtual string dimension_name(Dim_iter i)
Returns the name of the specified dimension.
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.
void append_dim(int size, const string &name="")
Add a dimension of a given size.
std::vector< dimension >::iterator Dim_iter
void rename_dim(const string &oldName="", const string &newName="")
Renames dimension.
virtual int dimension_size(Dim_iter i, bool constrained=false)
Returns the size of the dimension.
virtual void print_dap4(XMLWriter &xml, bool constrained=false)
Print the DAP4 representation of an array.
virtual bool check_semantics(string &msg, bool all=false)
Check semantic features of the Array.
std::vector< dimension >::const_iterator Dim_citer
virtual void print_as_map_xml(ostream &out, string space=" ", bool constrained=false)
virtual void reset_constraint()
Reset constraint to select entire array.
void add_var(BaseType *v, Part p=nil)
Add the BaseType pointer to this constructor type instance.
virtual ~Array()
The Array destructor.
virtual void print_xml_core(FILE *out, string space, bool constrained, string tag)
void prepend_dim(int size, const string &name="")
Array(const string &n, BaseType *v, bool is_dap4=false)
Array constructor.
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
virtual void print_val(ostream &out, string space="", bool print_decl_p=true)
Prints the value of the variable.
virtual unsigned int dimensions(bool constrained=false)
Return the total number of dimensions in the array.
virtual int dimension_stride(Dim_iter i, bool constrained=false)
Returns the stride value of the constraint.
Contains the attributes for a dataset.
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
virtual void set_name(const string &n)
Set the name of this attribute table.
virtual string get_name() const
Get the name of this attribute table.
void print_xml_writer(XMLWriter &xml)
virtual void print(FILE *out, string pad=" ", bool dereference=false)
Prints the attribute table.
virtual unsigned int get_size() const
Get the number of entries in this attribute table.
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 AttrTable & get_attr_table()
virtual string name() const
Returns the name of the class instance.
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.
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 is_constructor_type() const
Returns true if the instance is a constructor (i.e., Structure, Sequence or Grid) type variable.
virtual D4Attributes * attributes()
virtual std::string FQN() const
virtual bool send_p()
Should this variable be sent?
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
BaseType(const string &n, const Type &t, bool is_dap4=false)
The BaseType constructor.
virtual Type type() const
Returns the type of the class instance.
virtual void print_val(FILE *out, string space="", bool print_decl_p=true)
Prints the value of the variable.
void add_var_nocopy(BaseType *bt, Part part=nil) override
void transform_to_dap4(AttrTable &at)
copy attributes from DAP2 to DAP4
void transform_attrs_to_dap2(AttrTable *d2_attr_table)
Copy the attributes from this D4Attributes object to a DAP2 AttrTable.
vector< D4Dimension * >::iterator D4DimensionsIter
Iterator used for D4Dimensions.
void add_dim_nocopy(D4Dimension *dim)
D4DimensionsIter dim_end()
Get an iterator to the end of the dimensions.
D4DimensionsIter dim_begin()
Get an iterator to the start of the dimensions.
Holds a DAP4 enumeration.
D4Dimensions * dims()
Get the dimensions defined for this Group.
A class for error processing.
Holds the Grid data type.
virtual void set_array(Array *p_new_arr)
virtual Array * add_map(Array *p_new_map, bool add_copy)
A class for software fault reporting.
Holds a one-dimensional collection of DAP2 data types.
virtual void add_var(BaseType *v, Part p=nil)
Add the BaseType pointer to this constructor type instance.
virtual void set_length(int l)
virtual int length() const
virtual unsigned int width(bool constrained=false) const
Returns the width of the data, in bytes.
virtual void dump(ostream &strm) const
dumps information about this object
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
top level DAP object to house generic methods
string www2id(const string &in, const string &escape, const string &except)
Part
Names the parts of multi-section constructor data types.
string id2www(string in, const string &allowable)
int stride
The constraint stride.
string name
The name of this dimension.
bool use_sdim_for_slice
Used to control printing the DMR in data responses.
int start
The constraint start index.
int size
The unconstrained dimension size.
int stop
The constraint end index.
int c_size
Size of dimension once constrained.