46 #include "D4Attributes.h" 48 #include "D4Dimensions.h" 51 #include "D4EnumDefs.h" 53 #include "XMLWriter.h" 57 #include "InternalErr.h" 64 Array::dimension::dimension(D4Dimension *d) : dim(d), use_sdim_for_slice(true)
76 Array::_duplicate(
const Array &a)
82 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)
176 return new Array(*
this);
180 Array::operator=(
const Array &rhs)
185 dynamic_cast<Vector &
>(*this) = rhs;
204 if (!(*d).name.empty()) {
222 else if (d4_dim->size() != (
unsigned long) (*d).size) {
235 dest->set_is_dap4(
true);
254 std::vector<dimension>::iterator i = _shape.begin(), e = _shape.end();
257 while (old_i != old_e) {
258 if ((*i).dim == *old_i) {
259 (*i).dim = new_dims->find_dim((*old_i)->name());
298 if (v && v->
type() == dods_array_c) {
320 if (v && v->
type() == dods_array_c) {
322 Vector::add_var_nocopy(a.
var());
331 Vector::add_var_nocopy(v);
374 _shape.insert(_shape.begin(), d);
384 _shape.insert(_shape.begin(), d);
408 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
410 (*i).stop = (*i).size - 1;
412 (*i).c_size = (*i).size;
436 static const char *array_sss = \
437 "Invalid constraint parameters: At least one of the start, stride or stop \n\ 438 specified do not match the array variable.";
474 if (start >= d.
size || stop >= d.
size || stride > d.
size || stride <= 0)
475 throw Error(malformed_expr, array_sss);
477 if (((stop - start) / stride + 1) > d.
size)
478 throw Error(malformed_expr, array_sss);
484 d.
c_size = (stop - start) / stride + 1;
486 DBG(cerr <<
"add_constraint: c_size = " << d.
c_size << endl);
498 if (dim->constrained())
499 add_constraint(i, dim->c_start(), dim->c_stride(), dim->c_stop());
501 dim->set_used_by_projected_var(
true);
512 return _shape.begin() ;
519 return _shape.end() ;
535 return _shape.size();
560 if (!_shape.empty()) {
591 return (!_shape.empty()) ? (*i).start : 0;
615 return (!_shape.empty()) ? (*i).stop : 0;
640 return (!_shape.empty()) ? (*i).stride : 0;
663 "*This* array has no dimensions.");
670 return (!_shape.empty()) ? (*i).dim : 0;
676 if (!d_maps) d_maps =
new D4Maps(
this);
698 for (
Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
701 return length *
var()->
width(
false);
706 class PrintD4ArrayDimXMLWriter:
public unary_function<Array::dimension&, void> {
713 PrintD4ArrayDimXMLWriter(XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) { }
715 void operator()(Array::dimension &d)
721 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"Dim") < 0)
722 throw InternalErr(__FILE__, __LINE__,
"Could not write Dim element");
724 string name = (d.dim) ? d.dim->fully_qualified_name() : d.name;
727 if (!d_constrained && !name.empty()) {
728 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
729 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
731 else if (d.use_sdim_for_slice) {
732 assert(!name.empty());
733 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*) name.c_str())
734 < 0)
throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
738 size << (d_constrained ? d.c_size : d.size);
739 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size",
740 (
const xmlChar*) size.str().c_str()) < 0)
741 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
744 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
745 throw InternalErr(__FILE__, __LINE__,
"Could not end Dim element");
749 class PrintD4ConstructorVarXMLWriter:
public unary_function<BaseType*, void> {
753 PrintD4ConstructorVarXMLWriter(XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) { }
757 btp->print_dap4(xml, d_constrained);
761 class PrintD4MapXMLWriter:
public unary_function<D4Map*, void> {
765 PrintD4MapXMLWriter(XMLWriter &xml) : xml(xml) { }
767 void operator()(D4Map *m)
781 if (constrained && !
send_p())
return;
783 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
var()->
type_name().c_str()) < 0)
787 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
788 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
791 if (
var()->
type() == dods_enum_c) {
793 string path = e->enumeration()->name();
794 if (e->enumeration()->parent()) {
796 path =
static_cast<D4Group*
>(e->enumeration()->parent()->parent())->
FQN() + path;
798 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"enum", (
const xmlChar*)path.c_str()) < 0)
799 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for enum");
804 for_each(c.
var_begin(), c.
var_end(), PrintD4ConstructorVarXMLWriter(xml, constrained));
809 for_each(
dim_begin(),
dim_end(), PrintD4ArrayDimXMLWriter(xml, constrained));
813 for_each(maps()->map_begin(), maps()->map_end(), PrintD4MapXMLWriter(xml));
815 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
838 bool constraint_info,
bool constrained)
841 print_decl(oss, space, print_semi, constraint_info, constrained);
842 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
864 bool constraint_info,
bool constrained)
866 if (constrained && !
send_p())
870 var()->
print_decl(out, space,
false, constraint_info, constrained);
872 for (
Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
874 if ((*i).name !=
"") {
875 out <<
id2www((*i).name) <<
" = " ;
878 out << (*i).c_size <<
"]" ;
881 out << (*i).size <<
"]" ;
897 print_xml_writer_core(xml, constrained,
"Array");
898 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
908 print_xml_writer_core(xml, constrained,
"Array");
909 out << xml.get_doc();
919 print_xml_writer_core(xml, constrained,
"Map");
920 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
930 print_xml_writer_core(xml, constrained,
"Map");
931 out << xml.get_doc();
941 print_xml_writer_core(xml, constrained, tag);
942 fwrite(xml.get_doc(),
sizeof(char), xml.get_doc_size(), out);
952 print_xml_writer_core(xml, constrained, tag);
953 out << xml.get_doc();
959 print_xml_writer_core(xml, constrained,
"Array");
963 Array::print_as_map_xml_writer(
XMLWriter &xml,
bool constrained)
965 print_xml_writer_core(xml, constrained,
"Map");
968 class PrintArrayDimXMLWriter :
public unary_function<Array::dimension&, void>
973 PrintArrayDimXMLWriter(
XMLWriter &xml,
bool c) : xml(xml), d_constrained(c) {}
977 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)
"dimension") < 0)
978 throw InternalErr(__FILE__, __LINE__,
"Could not write dimension element");
981 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)d.
name.c_str()) < 0)
982 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
986 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"size", (
const xmlChar*)size.str().c_str()) < 0)
987 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
989 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
990 throw InternalErr(__FILE__, __LINE__,
"Could not end dimension element");
995 Array::print_xml_writer_core(
XMLWriter &xml,
bool constrained,
string tag)
997 if (constrained && !
send_p())
1000 if (xmlTextWriterStartElement(xml.get_writer(), (
const xmlChar*)tag.c_str()) < 0)
1001 throw InternalErr(__FILE__, __LINE__,
"Could not write " + tag +
" element");
1003 if (!
name().empty())
1004 if (xmlTextWriterWriteAttribute(xml.get_writer(), (
const xmlChar*)
"name", (
const xmlChar*)
name().c_str()) < 0)
1005 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1010 string tmp_name = btp->
name();
1015 for_each(
dim_begin(),
dim_end(), PrintArrayDimXMLWriter(xml, constrained));
1017 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1018 throw InternalErr(__FILE__, __LINE__,
"Could not end " + tag +
" element");
1034 unsigned int shape[])
1037 unsigned int i =
print_array(oss, index, dims, shape);
1038 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
1054 unsigned int Array::print_array(ostream &out,
unsigned int index,
unsigned int dims,
unsigned int shape[])
1060 if (shape[0] >= 1) {
1061 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1086 for (
unsigned i = 0; i < shape[0] - 1; ++i) {
1087 index =
print_array(out, index, dims - 1, shape + 1);
1091 index =
print_array(out, index, dims - 1, shape + 1);
1105 fwrite(oss.str().data(),
sizeof(char), oss.str().length(), out);
1122 unsigned int *shape =
new unsigned int[
dimensions(
true)];
1123 unsigned int index = 0;
1124 for (
Dim_iter i = _shape.begin(); i != _shape.end() && index <
dimensions(
true); ++i)
1129 delete [] shape; shape = 0;
1151 msg =
"An array variable must have dimensions";
1167 strm << DapIndent::LMarg <<
"Array::dump - (" 1168 << (
void *)
this <<
")" << endl ;
1169 DapIndent::Indent() ;
1171 strm << DapIndent::LMarg <<
"shape:" << endl ;
1172 DapIndent::Indent() ;
1175 unsigned int dim_num = 0 ;
1176 for (; i != ie; i++) {
1177 strm << DapIndent::LMarg <<
"dimension " << dim_num++ <<
":" 1179 DapIndent::Indent() ;
1180 strm << DapIndent::LMarg <<
"name: " << (*i).name << endl ;
1181 strm << DapIndent::LMarg <<
"size: " << (*i).size << endl ;
1182 strm << DapIndent::LMarg <<
"start: " << (*i).start << endl ;
1183 strm << DapIndent::LMarg <<
"stop: " << (*i).stop << endl ;
1184 strm << DapIndent::LMarg <<
"stride: " << (*i).stride << endl ;
1185 strm << DapIndent::LMarg <<
"constrained size: " << (*i).c_size
1187 DapIndent::UnIndent() ;
1189 DapIndent::UnIndent() ;
1190 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 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 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 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.
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 void dump(ostream &strm) const
dumps information about this object
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
virtual int length() const
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)
void append_dim(int size, const string &name="")
Add a dimension of a given size.
virtual void update_length(int size=0)
virtual Type type() const
Returns the type of the class instance.
D4DimensionsIter dim_begin()
Get an iterator to the start of the dimensions.
A class for software fault reporting.
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 string type_name() const
Returns the type of the class instance as a string.
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)
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.
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 std::string FQN() const
void prepend_dim(int size, const string &name="")
virtual string name() const
Returns the name of the class instance.
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 void dump(ostream &strm) const
dumps information about this object
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 void set_length(int l)
A class for error processing.
void transform_to_dap4(AttrTable &at)
copy attributes from DAP2 to DAP4
virtual BaseType * transform_to_dap4(D4Group *root, Constructor *container)
DAP2 to DAP4 transform.
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 bool send_p()
Should this variable be sent?
string id2www(string in, const string &allowable)
virtual unsigned int width(bool constrained=false) const
Returns the width of the data, in bytes.
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.