libdap Updated for version 3.18.1
Grid.cc
1
2// -*- mode: c++; c-basic-offset:4 -*-
3
4// This file is part of libdap, A C++ implementation of the OPeNDAP Data
5// Access Protocol.
6
7// Copyright (c) 2002,2003 OPeNDAP, Inc.
8// Author: James Gallagher <jgallagher@opendap.org>
9//
10// This library is free software; you can redistribute it and/or
11// modify it under the terms of the GNU Lesser General Public
12// License as published by the Free Software Foundation; either
13// version 2.1 of the License, or (at your option) any later version.
14//
15// This library is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18// Lesser General Public License for more details.
19//
20// You should have received a copy of the GNU Lesser General Public
21// License along with this library; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23//
24// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25
26// (c) COPYRIGHT URI/MIT 1994-1999
27// Please read the full copyright statement in the file COPYRIGHT_URI.
28//
29// Authors:
30// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
31
32// implementation for Grid.
33//
34// jhrg 9/15/94
35
36#include "config.h"
37
38// #define DODS_DEBUG
39
40#include <sstream>
41#include <functional>
42#include <algorithm>
43
44#include "Grid.h"
45#include "DDS.h"
46#include "Array.h" // for downcasts
47#include "util.h"
48#include "InternalErr.h"
49#include "escaping.h"
50#include "XDRStreamMarshaller.h"
51#include "debug.h"
52
53#include "XMLWriter.h"
54#include "DMR.h"
55#include "D4Group.h"
56#include "D4Maps.h"
57#include "D4Attributes.h"
58
59using namespace std;
60
61namespace libdap {
62
63void
64Grid::m_duplicate(const Grid &s)
65{
66 // TODO revisit this code once/if the class is switched from using it's
67 // own vars to those in Constructor. jhrg 4/3/13
68
69 // copy the weak pointer - Constructor will take care of copying
70 // the 'strong' pointers.
71 //d_array_var = s.d_array_var;
72 d_is_array_set = s.d_is_array_set;
73}
74
84Grid::Grid(const string &n) : Constructor(n, dods_grid_c), d_is_array_set(false)
85{}
86
98Grid::Grid(const string &n, const string &d)
99 : Constructor(n, d, dods_grid_c), d_is_array_set(false)
100{}
101
103Grid::Grid(const Grid &rhs) : Constructor(rhs)
104{
105 m_duplicate(rhs);
106}
107
108Grid::~Grid()
109{
110 //d_array_var = 0; // Weak pointer; object will be freed by Constructor
111}
112
113BaseType *
115{
116 return new Grid(*this);
117}
118
119Grid &
120Grid::operator=(const Grid &rhs)
121{
122 if (this == &rhs)
123 return *this;
124
125 // Removed this; it makes this operator= work differently than the rest
126#if 0
127 delete d_array_var; d_array_var = 0;
128
129 for (Map_iter i = d_map_vars.begin(); i != d_map_vars.end(); i++) {
130 BaseType *btp = *i ;
131 delete btp ;
132 }
133#endif
134
135 dynamic_cast<Constructor &>(*this) = rhs;
136
137 m_duplicate(rhs);
138
139 return *this;
140}
141
142// FIXME transform_to_dap4 probably needs to run for side effect only.
143// drop the return BT and add variables to the D4Group that is passed
144// in instead of the DMR.
145//
146// Also need to handle the case where a Grid is part of a Structure
147BaseType *
149{
150 BaseType *btp = array_var()->transform_to_dap4(root, container);
151 Array *coverage = static_cast<Array*>(btp);
152 if (!coverage)
153 throw InternalErr(__FILE__, __LINE__, "Expected an Array while transforming a Grid (coverage)");
154
155 coverage->set_parent(container);
156
157 // Next find the maps; add them to the coverage and to the container,
158 // the latter only on the condition that they are not already there.
159
160 for (Map_iter i = map_begin(), e = map_end(); i != e; ++i) {
161 btp = (*i)->transform_to_dap4(root, container);
162 Array *map = static_cast<Array*>(btp);
163 if (!map)
164 throw InternalErr(__FILE__, __LINE__, "Expected an Array while transforming a Grid (map)");
165
166 // map must be non-null (Grids cannot contain Grids in DAP2)
167 if (map) {
168 // Only add the map/array if it not already present; given the scoping rules
169 // for DAP2 and the assumption the DDS is valid, testing for the same name
170 // is good enough.
171 if (!root->var(map->name())) {
172 map->set_parent(container);
173 container->add_var_nocopy(map); // this adds the array to the container
174 }
175 D4Map *dap4_map = new D4Map(map->name(), map, coverage); // bind the 'map' to the coverage
176 coverage->maps()->add_map(dap4_map); // bind the coverage to the map
177 }
178 else {
179 throw InternalErr(__FILE__, __LINE__,
180 "transform_to_dap4() returned a null value where there can be no Grid.");
181 }
182 }
183
184 container->add_var_nocopy(coverage);
185
186 // Since a Grid (DAP2) to a Coverage (DAP4) removes a lexical scope
187 // in favor of a set of relations, Grid::transform_to_dap4() does not
188 // return a BaseType*. Callers should assume it has correctly added
189 // stuff to the container and group.
190 return 0;
191}
192
193
199bool
201{
202 return true;
203}
204
217void
219{
220 if (!bt)
221 throw InternalErr(__FILE__, __LINE__, "Passing NULL pointer as variable to be added.");
222
223 if (part == array && d_is_array_set/*get_array()*/) {
224 // Avoid leaking memory... Function is add, not set, so it is an error to call again for the array part.
225 throw InternalErr(__FILE__, __LINE__, "Error: Grid::add_var called with part==Array, but the array was already set!");
226 }
227
228 // avoid obvious broken semantics
229 if (!dynamic_cast<Array*>(bt)) {
230 throw InternalErr(__FILE__, __LINE__, "Grid::add_var(): object is not an Array!");
231 }
232
233 // Set to the clone of bt if we get that far.
234 BaseType* bt_clone = 0;
235
236 switch (part) {
237
238 case array: {
239 // Add it as a copy to preserve old semantics. This sets parent too.
240 bt_clone = bt->ptr_duplicate();
241 set_array(static_cast<Array*>(bt_clone));
242 }
243 break;
244
245 case maps: {
246 bt_clone = bt->ptr_duplicate();
247 bt_clone->set_parent(this);
248 d_vars.push_back(bt_clone);
249 }
250 break;
251
252 default: {
253 if (!d_is_array_set) {
254 // Add it as a copy to preserve old semantics. This sets parent too.
255 bt_clone = bt->ptr_duplicate();
256 set_array(static_cast<Array*>(bt_clone));
257 }
258 else {
259 bt_clone = bt->ptr_duplicate();
260 bt_clone->set_parent(this);
261 d_vars.push_back(bt_clone);
262 }
263 }
264 break;
265 }
266}
267
283void
285{
286 if (!bt)
287 throw InternalErr(__FILE__, __LINE__, "Passing NULL pointer as variable to be added.");
288
289 if (part == array && d_is_array_set/*get_array()*/) {
290 // Avoid leaking memory... Function is add, not set, so it is an error to call again for the array part.
291 throw InternalErr(__FILE__, __LINE__, "Error: Grid::add_var called with part==Array, but the array was already set!");
292 }
293
294 // avoid obvious broken semantics
295 if (!dynamic_cast<Array*>(bt)) {
296 throw InternalErr(__FILE__, __LINE__, "Grid::add_var(): object is not an Array!");
297 }
298
299 bt->set_parent(this);
300
301 switch (part) {
302
303 case array: {
304 // Refactored to use new set_array ([mjohnson 11 nov 2009])
305 set_array(static_cast<Array*>(bt));
306 }
307 break;
308
309 case maps: {
310 // FIXME Why is this commented out?
311 //bt->set_parent(this);
312 d_vars.push_back(bt);
313 }
314 break;
315
316 default: {
317 if (!d_is_array_set) {
318 // Refactored to use new set_array ([mjohnson 11 nov 2009])
319 // avoid obvious broken semantics
320 set_array(static_cast<Array*>(bt));
321 }
322 else {
323 d_vars.push_back(bt);
324 }
325 }
326 break;
327 }
328}
329
343void Grid::set_array(Array* p_new_arr)
344{
345 if (!p_new_arr) {
346 throw InternalErr(__FILE__, __LINE__, "Grid::set_array(): Cannot set to null!");
347 }
348
349 // Make sure not same memory, this would be evil.
350 if (p_new_arr == get_array()) {
351 return;
352 }
353
354 p_new_arr->set_parent(this);
355
356 // Three cases: 1. There are no variables set for this grid at all
357 // 2. There are maps but no array
358 // 3. There is already an array set (and maybe maps).
359 // NB: d_array_var is a weak pointer to the Grid's Array
360 if (d_vars.size() == 0) {
361 d_vars.push_back(p_new_arr);
362 }
363 else if (!d_is_array_set) {
364 d_vars.insert(d_vars.begin(), p_new_arr);
365 }
366 else {
367 // clean out old array
368 delete get_array();
369 d_vars[0] = p_new_arr;
370 }
371
372 d_is_array_set = true;
373#if 0
374 // store the array pointer locally
375 d_array_var = p_new_arr;
376
377 // Set the parent
378 d_array_var->set_parent(this);
379#endif
380}
381
408Array*
409Grid::add_map(Array* p_new_map, bool add_as_copy)
410{
411 if (!p_new_map)
412 throw InternalErr(__FILE__, __LINE__, "Grid::add_map(): cannot have p_new_map null!");
413
414 if (add_as_copy)
415 p_new_map = static_cast<Array*>(p_new_map->ptr_duplicate());
416
417 p_new_map->set_parent(this);
418
419 d_vars.push_back(p_new_map);
420
421 // return the one that got put into the Grid.
422 return p_new_map;
423}
424
437Array*
438Grid::prepend_map(Array* p_new_map, bool add_copy)
439{
440 if (add_copy)
441 {
442 p_new_map = static_cast<Array*>(p_new_map->ptr_duplicate());
443 }
444
445 p_new_map->set_parent(this);
446 d_vars.insert(map_begin(), p_new_map);
447
448 return p_new_map;
449}
450
454BaseType *
456{
457 //return d_array_var;
458 // FIXME Should really test that the array has not be set; maps might be added first. jhrg 5/9/13
459#if 0
460 if (d_array_var)
461 cerr << "In array_var(), d_array_var holds a " << d_array_var->type_name() << endl;
462 else
463 cerr << "In array_var(), d_array_var is null" << endl;
464#endif
465 return d_is_array_set /*d_vars.size() > 0*/ ? *d_vars.begin() : 0;
466}
467
471Array *
473{
474 return dynamic_cast<Array*>(array_var());
475}
476
478Grid::Map_iter
480{
481 // The maps are stored in the second and subsequent elements of the
482 // d_var vector<BaseType*> of Constructor _unless_ the Array part
483 // has yet to be set. In the latter case, there are only maps in
484 // d_vars
485 return d_is_array_set/*(d_array_var != 0)*/ ? d_vars.begin() + 1: d_vars.begin();
486}
487
490Grid::Map_iter
492{
493 return d_vars.end();
494}
495
497Grid::Map_riter
499{
500 // see above
501 // return d_is_array_set/*(d_array_var != 0)*/ ? d_vars.rbegin() + 1: d_vars.rbegin();
502 return d_vars.rbegin();
503}
504
507Grid::Map_riter
509{
510 return d_is_array_set ? d_vars.rend() - 1: d_vars.rend();
511}
512
516Grid::Map_iter
518{
519 // return map_begin() + i;
520 return d_is_array_set ? map_begin() + 1 + i : map_begin() + i;
521}
522
538int
539Grid::components(bool constrained)
540{
541 int comp;
542
543 if (constrained) {
544 comp = get_array()->send_p() ? 1 : 0;
545
546 for (Map_iter i = map_begin(); i != map_end(); i++) {
547 if ((*i)->send_p()) {
548 comp++;
549 }
550 }
551 }
552 else {
553 comp = d_vars.size();
554 }
555
556 return comp;
557}
558
560{
561 AttrTable *at = at_container->get_attr_table(name());
562
563 if (at) {
564 at->set_is_global_attribute(false);
565
567
568 Map_iter map = map_begin();
569 while (map != map_end()) {
570 (*map)->transfer_attributes(at);
571 map++;
572 }
573
574 // Trick: If an attribute that's within the container 'at' still has its
575 // is_global_attribute property set, then it's not really a global attr
576 // but instead an attribute that belongs to this Grid.
577 AttrTable::Attr_iter at_p = at->attr_begin();
578 while (at_p != at->attr_end()) {
579 if (at->is_global_attribute(at_p)) {
580 if (at->get_attr_type(at_p) == Attr_container)
582 else
583 get_attr_table().append_attr(at->get_name(at_p), at->get_type(at_p), at->get_attr_vector(at_p));
584 }
585
586 at_p++;
587 }
588 }
589}
590
591// When projected (using whatever the current constraint provides in the way
592// of a projection), is the object still a Grid?
593
610bool
612{
613 // For each dimension in the Array part, check the corresponding Map
614 // vector to make sure it is present in the projected Grid. If for each
615 // projected dimension in the Array component, there is a matching Map
616 // vector, then the Grid is valid.
617 bool valid = true;
618 Array *a = get_array();
619
620 // Don't bother checking if the Array component is not included.
621 if (!a->send_p())
622 return false;
623
624 // If only one part is being sent, it's clearly not a grid (it must be
625 // the array part of the Grid that's being sent (given that the above
626 // test passed and the array is being sent).
627 if (components(true) == 1)
628 return false;
629
630 Array::Dim_iter d = a->dim_begin() ;
631 Map_iter m = map_begin() ;
632
633 while (valid && d != a->dim_end() && m != map_end()) {
634 Array &map = dynamic_cast<Array&>(**m);
635 if (a->dimension_size(d, true) && map.send_p()) {
636 // Check the matching Map vector; the Map projection must equal
637 // the Array dimension projection
638 Array::Dim_iter fd = map.dim_begin(); // Maps have only one dim!
639 valid = map.dimension_start(fd, true) == a->dimension_start(d, true)
640 && map.dimension_stop(fd, true) == a->dimension_stop(d, true)
641 && map.dimension_stride(fd, true) == a->dimension_stride(d, true);
642 }
643 else {
644 valid = false;
645 }
646
647 d++, m++;
648 }
649
650 return valid;
651}
652
654void
656{
658 for (Map_iter m = map_begin(); m != map_end(); ++m)
659 dynamic_cast<Array&>(*(*m)).clear_constraint();
660}
661
662void
663Grid::print_decl(FILE *out, string space, bool print_semi,
664 bool constraint_info, bool constrained)
665{
666 ostringstream oss;
667 print_decl(oss, space, print_semi, constraint_info, constrained);
668 fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
669}
670
671void
672Grid::print_decl(ostream &out, string space, bool print_semi,
673 bool constraint_info, bool constrained)
674{
675 if (constrained && !send_p())
676 return;
677
678 // See comment for the FILE* version of this method.
679 if (constrained && !projection_yields_grid()) {
680 out << space << "Structure {\n" ;
681
682 get_array()->print_decl(out, space + " ", true, constraint_info,
683 constrained);
684
685 for (Map_citer i = map_begin(); i != map_end(); i++) {
686 (*i)->print_decl(out, space + " ", true,
687 constraint_info, constrained);
688 }
689
690 out << space << "} " << id2www(name()) ;
691 }
692 else {
693 // The number of elements in the (projected) Grid must be such that
694 // we have a valid Grid object; send it as such.
695 out << space << type_name() << " {\n" ;
696
697 out << space << " Array:\n" ;
698 get_array()->print_decl(out, space + " ", true, constraint_info,
699 constrained);
700
701 out << space << " Maps:\n" ;
702 for (Map_citer i = map_begin(); i != map_end(); i++) {
703 (*i)->print_decl(out, space + " ", true,
704 constraint_info, constrained);
705 }
706
707 out << space << "} " << id2www(name()) ;
708 }
709
710 if (constraint_info) {
711 if (send_p())
712 out << ": Send True";
713 else
714 out << ": Send False";
715 }
716
717 if (print_semi)
718 out << ";\n" ;
719
720 return;
721}
722
726void
727Grid::print_xml(FILE *out, string space, bool constrained)
728{
729 XMLWriter xml(space);
730 print_xml_writer(xml, constrained);
731 fwrite(xml.get_doc(), sizeof(char), xml.get_doc_size(), out);
732}
733
737void
738Grid::print_xml(ostream &out, string space, bool constrained)
739{
740 XMLWriter xml(space);
741 print_xml_writer(xml, constrained);
742 out << xml.get_doc();
743}
744
745
746class PrintGridFieldXMLWriter : public unary_function<BaseType *, void>
747{
748 XMLWriter &d_xml;
749 bool d_constrained;
750 string d_tag;
751public:
752 PrintGridFieldXMLWriter(XMLWriter &x, bool c, const string &t = "Map")
753 : d_xml(x), d_constrained(c), d_tag(t)
754 {}
755
756 void operator()(BaseType *btp)
757 {
758 Array *a = dynamic_cast<Array*>(btp);
759 if (!a)
760 throw InternalErr(__FILE__, __LINE__, "Expected an Array.");
761 a->print_xml_writer_core(d_xml, d_constrained, d_tag);
762 }
763};
764
765void
766Grid::print_xml_writer(XMLWriter &xml, bool constrained)
767{
768 if (constrained && !send_p())
769 return;
770
771 if (constrained && !projection_yields_grid()) {
772 if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Structure") < 0)
773 throw InternalErr(__FILE__, __LINE__, "Could not write Structure element");
774
775 if (!name().empty())
776 if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
777 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
778
780
781 get_array()->print_xml_writer(xml, constrained);
782
783 for_each(map_begin(), map_end(),
784 PrintGridFieldXMLWriter(xml, constrained, "Array"));
785
786 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
787 throw InternalErr(__FILE__, __LINE__, "Could not end Structure element");
788 }
789 else {
790 // The number of elements in the (projected) Grid must be such that
791 // we have a valid Grid object; send it as such.
792 if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Grid") < 0)
793 throw InternalErr(__FILE__, __LINE__, "Could not write Grid element");
794
795 if (!name().empty())
796 if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)name().c_str()) < 0)
797 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
798
800
801 get_array()->print_xml_writer(xml, constrained);
802
803 for_each(map_begin(), map_end(),
804 PrintGridFieldXMLWriter(xml, constrained, "Map"));
805
806 if (xmlTextWriterEndElement(xml.get_writer()) < 0)
807 throw InternalErr(__FILE__, __LINE__, "Could not end Grid element");
808 }
809}
810
811void
812Grid::print_val(FILE *out, string space, bool print_decl_p)
813{
814 ostringstream oss;
815 print_val(oss, space, print_decl_p);
816 fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
817}
818
819void
820Grid::print_val(ostream &out, string space, bool print_decl_p)
821{
822 if (print_decl_p) {
823 print_decl(out, space, false);
824 out << " = " ;
825 }
826
827 // If we are printing a value on the client-side, projection_yields_grid
828 // should not be called since we don't *have* a projection without a
829 // Constraint. I think that if we are here and send_p() is not true, then
830 // the value of this function should be ignored. 4/6/2000 jhrg
831 bool pyg = projection_yields_grid(); // hack 12/1/99 jhrg
832 if (pyg || !send_p())
833 out << "{ Array: " ;
834 else
835 out << "{" ;
836 get_array()->print_val(out, "", false);
837 if (pyg || !send_p())
838 out << " Maps: " ;
839 for (Map_citer i = map_begin(); i != map_end(); i++, (void)(i != map_end() && out << ", ")) {
840 (*i)->print_val(out, "", false);
841 }
842 out << " }" ;
843
844 if (print_decl_p)
845 out << ";\n" ;
846}
847
848// Grids have ugly semantics.
849
854bool
855Grid::check_semantics(string &msg, bool all)
856{
858 return false;
859
860 msg = "";
861
862 if (!get_array()) {
863 msg += "Null grid base array in `" + name() + "'\n";
864 return false;
865 }
866
867 // Is it an array?
868 if (get_array()->type() != dods_array_c) {
869 msg += "Grid `" + name() + "'s' member `" + get_array()->name() + "' must be an array\n";
870 return false;
871 }
872
873 Array *av = (Array *)get_array(); // past test above, must be an array
874
875 // Array must be of a simple_type.
876 if (!av->var()->is_simple_type()) {
877 msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
878 return false;
879 }
880
881 // enough maps?
882 if ((unsigned)d_vars.size()-1 != av->dimensions()) {
883 msg += "The number of map variables for grid `" + this->name() + "' does not match the number of dimensions of `";
884 msg += av->name() + "'\n";
885 return false;
886 }
887
888 const string array_var_name = av->name();
889 Array::Dim_iter asi = av->dim_begin() ;
890 for (Map_iter mvi = map_begin(); mvi != map_end(); mvi++, asi++) {
891
892 BaseType *mv = *mvi;
893
894 // check names
895 if (array_var_name == mv->name()) {
896 msg += "Grid map variable `" + mv->name() + "' conflicts with the grid array name in grid `" + name() + "'\n";
897 return false;
898 }
899 // check types
900 if (mv->type() != dods_array_c) {
901 msg += "Grid map variable `" + mv->name() + "' is not an array\n";
902 return false;
903 }
904
905 Array *mv_a = (Array *)mv; // downcast to (Array *)
906
907 // Array must be of a simple_type.
908 if (!mv_a->var()->is_simple_type()) {
909 msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
910 return false;
911 }
912
913 // check shape
914 if (mv_a->dimensions() != 1) {// maps must have one dimension
915 msg += "Grid map variable `" + mv_a->name() + "' must be only one dimension\n";
916 return false;
917 }
918 // size of map must match corresponding array dimension
919 Array::Dim_iter mv_asi = mv_a->dim_begin() ;
920 int mv_a_size = mv_a->dimension_size(mv_asi) ;
921 int av_size = av->dimension_size(asi) ;
922 if (mv_a_size != av_size) {
923 msg += "Grid map variable `" + mv_a->name() + "'s' size does not match the size of array variable '";
924 msg += get_array()->name() + "'s' cooresponding dimension\n";
925 return false;
926 }
927 }
928
929 if (all) {
930 if (!get_array()->check_semantics(msg, true))
931 return false;
932 for (Map_iter mvi = map_begin(); mvi != map_end(); mvi++) {
933 if (!(*mvi)->check_semantics(msg, true)) {
934 return false;
935 }
936 }
937 }
938
939 return true;
940}
941
950void
951Grid::dump(ostream &strm) const
952{
953 strm << DapIndent::LMarg << "Grid::dump - ("
954 << (void *)this << ")" << endl ;
955 DapIndent::Indent() ;
956 Constructor::dump(strm) ;
957
958 DapIndent::UnIndent() ;
959}
960
961} // namespace libdap
962
A multidimensional array of identical data types.
Definition: Array.h:113
virtual int dimension_start(Dim_iter i, bool constrained=false)
Return the start index of a dimension.
Definition: Array.cc:589
virtual void clear_constraint()
Clears the projection; add each projected dimension explicitly using add_constraint.
Definition: Array.cc:429
Dim_iter dim_end()
Definition: Array.cc:517
virtual BaseType * ptr_duplicate()
Definition: Array.cc:174
virtual int dimension_stop(Dim_iter i, bool constrained=false)
Return the stop index of the constraint.
Definition: Array.cc:613
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.
Definition: Array.cc:862
std::vector< dimension >::iterator Dim_iter
Definition: Array.h:204
virtual int dimension_size(Dim_iter i, bool constrained=false)
Returns the size of the dimension.
Definition: Array.cc:556
Dim_iter dim_begin()
Definition: Array.cc:510
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
Definition: Array.cc:954
virtual void print_val(ostream &out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition: Array.cc:1106
virtual unsigned int dimensions(bool constrained=false)
Return the total number of dimensions in the array.
Definition: Array.cc:533
virtual int dimension_stride(Dim_iter i, bool constrained=false)
Returns the stride value of the constraint.
Definition: Array.cc:638
Contains the attributes for a dataset.
Definition: AttrTable.h:143
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition: AttrTable.cc:409
virtual AttrTable * get_attr_table(const string &name)
Get an attribute container.
Definition: AttrTable.cc:606
virtual Attr_iter attr_end()
Definition: AttrTable.cc:718
virtual string get_type(const string &name)
Get the type name of an attribute within this attribute table.
Definition: AttrTable.cc:612
virtual vector< string > * get_attr_vector(const string &name)
Get a vector-valued attribute.
Definition: AttrTable.cc:652
virtual unsigned int append_attr(const string &name, const string &type, const string &value)
Add an attribute to the table.
Definition: AttrTable.cc:306
virtual Attr_iter attr_begin()
Definition: AttrTable.cc:710
virtual string get_name() const
Get the name of this attribute table.
Definition: AttrTable.cc:237
void print_xml_writer(XMLWriter &xml)
Definition: AttrTable.cc:1424
virtual AttrType get_attr_type(const string &name)
Get the type of an attribute.
Definition: AttrTable.cc:620
The basic data type for the DODS DAP types.
Definition: BaseType.h:118
virtual string type_name() const
Returns the type of the class instance as a string.
Definition: BaseType.cc:324
virtual AttrTable & get_attr_table()
Definition: BaseType.cc:527
virtual string name() const
Returns the name of the class instance.
Definition: BaseType.cc:265
virtual void set_parent(BaseType *parent)
Definition: BaseType.cc:654
virtual BaseType * transform_to_dap4(D4Group *root, Constructor *container)
DAP2 to DAP4 transform.
Definition: BaseType.cc:215
virtual bool send_p()
Should this variable be sent?
Definition: BaseType.cc:499
virtual bool is_simple_type() const
Returns true if the instance is a numeric, string or URL type variable.
Definition: BaseType.cc:338
virtual BaseType * ptr_duplicate()=0
virtual void transfer_attributes(AttrTable *at)
Definition: BaseType.cc:589
virtual bool check_semantics(string &msg, bool all=false)
Compare an object's current state with the semantics of its type.
Definition: BaseType.cc:1130
virtual Type type() const
Returns the type of the class instance.
Definition: BaseType.cc:310
virtual BaseType * var(const string &name, bool exact_match=true, btp_stack *s=0)
btp_stack no longer needed; use back pointers (BaseType::get_parent())
Definition: Constructor.cc:242
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Constructor.cc:827
virtual void add_var_nocopy(BaseType *bt, Part part=nil)
Definition: Constructor.cc:407
void add_map(D4Map *map)
Definition: D4Maps.h:115
Holds the Grid data type.
Definition: Grid.h:123
virtual BaseType * ptr_duplicate()
Definition: Grid.cc:114
BaseType * array_var()
Returns the Grid Array.
Definition: Grid.cc:455
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
Definition: Grid.cc:738
Map_iter map_begin()
Returns an iterator referencing the first Map vector.
Definition: Grid.cc:479
Map_iter get_map_iter(int i)
Definition: Grid.cc:517
virtual void set_array(Array *p_new_arr)
Definition: Grid.cc:343
virtual void clear_constraint()
Definition: Grid.cc:655
virtual void print_val(ostream &out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition: Grid.cc:820
virtual void print_decl(ostream &out, string space=" ", bool print_semi=true, bool constraint_info=false, bool constrained=false)
Print an ASCII representation of the variable structure.
Definition: Grid.cc:672
virtual Array * prepend_map(Array *p_new_map, bool add_copy)
Definition: Grid.cc:438
Grid(const string &n)
The Grid constructor.
Definition: Grid.cc:84
Array * get_array()
Returns the Grid Array. This method returns the array using an Array*, so no cast is required.
Definition: Grid.cc:472
virtual void transfer_attributes(AttrTable *at_container)
Definition: Grid.cc:559
virtual bool projection_yields_grid()
Definition: Grid.cc:611
Map_iter map_end()
Definition: Grid.cc:491
Map_riter map_rend()
Definition: Grid.cc:508
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Grid.cc:951
virtual Array * add_map(Array *p_new_map, bool add_copy)
Definition: Grid.cc:409
virtual int components(bool constrained=false)
Returns the number of components in the Grid object.
Definition: Grid.cc:539
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
Definition: Grid.cc:766
virtual bool check_semantics(string &msg, bool all=false)
Return true if this Grid is well formed.
Definition: Grid.cc:855
virtual void add_var(BaseType *bt, Part part)
Definition: Grid.cc:218
virtual BaseType * transform_to_dap4(D4Group *root, Constructor *container)
DAP2 to DAP4 transform.
Definition: Grid.cc:148
virtual void add_var_nocopy(BaseType *bt, Part part)
Definition: Grid.cc:284
Map_riter map_rbegin()
Returns an iterator referencing the first Map vector.
Definition: Grid.cc:498
virtual bool is_dap2_only_type()
Definition: Grid.cc:200
A class for software fault reporting.
Definition: InternalErr.h:65
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
Definition: Vector.cc:434
Part
Names the parts of multi-section constructor data types.
Definition: Type.h:48
string id2www(string in, const string &allowable)
Definition: escaping.cc:153