libdap  Updated for version 3.18.3
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 
59 using namespace std;
60 
61 namespace libdap {
62 
63 void
64 Grid::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 
84 Grid::Grid(const string &n) : Constructor(n, dods_grid_c), d_is_array_set(false)
85 {}
86 
98 Grid::Grid(const string &n, const string &d)
99  : Constructor(n, d, dods_grid_c), d_is_array_set(false)
100 {}
101 
103 Grid::Grid(const Grid &rhs) : Constructor(rhs)
104 {
105  m_duplicate(rhs);
106 }
107 
108 Grid::~Grid()
109 {
110  //d_array_var = 0; // Weak pointer; object will be freed by Constructor
111 }
112 
113 BaseType *
115 {
116  return new Grid(*this);
117 }
118 
119 Grid &
120 Grid::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
147 BaseType *
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 
199 bool
201 {
202  return true;
203 }
204 
217 void
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 
283 void
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 
343 void 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 
408 Array*
409 Grid::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 
437 Array*
438 Grid::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 
454 BaseType *
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 
471 Array *
473 {
474  return dynamic_cast<Array*>(array_var());
475 }
476 
478 Grid::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 
490 Grid::Map_iter
492 {
493  return d_vars.end();
494 }
495 
497 Grid::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 
507 Grid::Map_riter
509 {
510  return d_is_array_set ? d_vars.rend() - 1: d_vars.rend();
511 }
512 
516 Grid::Map_iter
518 {
519  // return map_begin() + i;
520  return d_is_array_set ? map_begin() + 1 + i : map_begin() + i;
521 }
522 
538 int
539 Grid::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)
581  get_attr_table().append_container(new AttrTable(*at->get_attr_table(at_p)), at->get_name(at_p));
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 
610 bool
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 
654 void
656 {
658  for (Map_iter m = map_begin(); m != map_end(); ++m)
659  dynamic_cast<Array&>(*(*m)).clear_constraint();
660 }
661 
662 void
663 Grid::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 
671 void
672 Grid::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 
726 void
727 Grid::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 
737 void
738 Grid::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 
746 class PrintGridFieldXMLWriter : public unary_function<BaseType *, void>
747 {
748  XMLWriter &d_xml;
749  bool d_constrained;
750  string d_tag;
751 public:
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 
765 void
766 Grid::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 
811 void
812 Grid::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 
819 void Grid::print_val(ostream &out, string space, bool print_decl_p)
820 {
821  if (print_decl_p) {
822  print_decl(out, space, false);
823  out << " = ";
824  }
825 
826  // If we are printing a value on the client-side, projection_yields_grid
827  // should not be called since we don't *have* a projection without a
828  // Constraint. I think that if we are here and send_p() is not true, then
829  // the value of this function should be ignored. 4/6/2000 jhrg
830  bool pyg = projection_yields_grid(); // hack 12/1/99 jhrg
831  if (pyg || !send_p())
832  out << "{ Array: ";
833  else
834  out << "{";
835 
836  get_array()->print_val(out, "", false);
837 
838  if (pyg || !send_p()) out << " Maps: ";
839 
840  for (Map_citer i = map_begin(); i != map_end(); i++, (void) (i != map_end() && out << ", ")) {
841  (*i)->print_val(out, "", false);
842  }
843 
844  out << " }";
845 
846  if (print_decl_p) out << ";\n";
847 }
848 
849 // Grids have ugly semantics.
850 
855 bool
856 Grid::check_semantics(string &msg, bool all)
857 {
858  if (!BaseType::check_semantics(msg))
859  return false;
860 
861  msg = "";
862 
863  if (!get_array()) {
864  msg += "Null grid base array in `" + name() + "'\n";
865  return false;
866  }
867 
868  // Is it an array?
869  if (get_array()->type() != dods_array_c) {
870  msg += "Grid `" + name() + "'s' member `" + get_array()->name() + "' must be an array\n";
871  return false;
872  }
873 
874  Array *av = (Array *)get_array(); // past test above, must be an array
875 
876  // Array must be of a simple_type.
877  if (!av->var()->is_simple_type()) {
878  msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
879  return false;
880  }
881 
882  // enough maps?
883  if ((unsigned)d_vars.size()-1 != av->dimensions()) {
884  msg += "The number of map variables for grid `" + this->name() + "' does not match the number of dimensions of `";
885  msg += av->name() + "'\n";
886  return false;
887  }
888 
889  const string array_var_name = av->name();
890  Array::Dim_iter asi = av->dim_begin() ;
891  for (Map_iter mvi = map_begin(); mvi != map_end(); mvi++, asi++) {
892 
893  BaseType *mv = *mvi;
894 
895  // check names
896  if (array_var_name == mv->name()) {
897  msg += "Grid map variable `" + mv->name() + "' conflicts with the grid array name in grid `" + name() + "'\n";
898  return false;
899  }
900  // check types
901  if (mv->type() != dods_array_c) {
902  msg += "Grid map variable `" + mv->name() + "' is not an array\n";
903  return false;
904  }
905 
906  Array *mv_a = (Array *)mv; // downcast to (Array *)
907 
908  // Array must be of a simple_type.
909  if (!mv_a->var()->is_simple_type()) {
910  msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
911  return false;
912  }
913 
914  // check shape
915  if (mv_a->dimensions() != 1) {// maps must have one dimension
916  msg += "Grid map variable `" + mv_a->name() + "' must be only one dimension\n";
917  return false;
918  }
919  // size of map must match corresponding array dimension
920  Array::Dim_iter mv_asi = mv_a->dim_begin() ;
921  int mv_a_size = mv_a->dimension_size(mv_asi) ;
922  int av_size = av->dimension_size(asi) ;
923  if (mv_a_size != av_size) {
924  msg += "Grid map variable `" + mv_a->name() + "'s' size does not match the size of array variable '";
925  msg += get_array()->name() + "'s' cooresponding dimension\n";
926  return false;
927  }
928  }
929 
930  if (all) {
931  if (!get_array()->check_semantics(msg, true))
932  return false;
933  for (Map_iter mvi = map_begin(); mvi != map_end(); mvi++) {
934  if (!(*mvi)->check_semantics(msg, true)) {
935  return false;
936  }
937  }
938  }
939 
940  return true;
941 }
942 
951 void
952 Grid::dump(ostream &strm) const
953 {
954  strm << DapIndent::LMarg << "Grid::dump - ("
955  << (void *)this << ")" << endl ;
956  DapIndent::Indent() ;
957  Constructor::dump(strm) ;
958 
959  DapIndent::UnIndent() ;
960 }
961 
962 } // namespace libdap
963 
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
Definition: Array.cc:954
virtual string name() const
Returns the name of the class instance.
Definition: BaseType.cc:265
Map_riter map_rend()
Definition: Grid.cc:508
virtual Attr_iter attr_end()
Definition: AttrTable.cc:718
virtual unsigned int dimensions(bool constrained=false)
Return the total number of dimensions in the array.
Definition: Array.cc:533
virtual Array * prepend_map(Array *p_new_map, bool add_copy)
Definition: Grid.cc:438
virtual void add_var_nocopy(BaseType *bt, Part part)
Definition: Grid.cc:284
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
Part
Names the parts of multi-section constructor data types.
Definition: Type.h:48
Contains the attributes for a dataset.
Definition: AttrTable.h:142
virtual string get_type(const string &name)
Get the type name of an attribute within this attribute table.
Definition: AttrTable.cc:612
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
Definition: Grid.cc:738
virtual string get_name() const
Get the name of this attribute table.
Definition: AttrTable.cc:237
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Grid.cc:952
STL namespace.
void print_xml_writer(XMLWriter &xml)
Definition: AttrTable.cc:1424
virtual bool is_simple_type() const
Returns true if the instance is a numeric, string or URL type variable.
Definition: BaseType.cc:338
virtual void add_var_nocopy(BaseType *bt, Part part=nil)
Definition: Constructor.cc:407
Map_iter map_end()
Definition: Grid.cc:491
virtual void set_parent(BaseType *parent)
Definition: BaseType.cc:654
A class for software fault reporting.
Definition: InternalErr.h:64
Dim_iter dim_end()
Definition: Array.cc:517
virtual int components(bool constrained=false)
Returns the number of components in the Grid object.
Definition: Grid.cc:539
Map_riter map_rbegin()
Returns an iterator referencing the first Map vector.
Definition: Grid.cc:498
virtual void set_array(Array *p_new_arr)
Definition: Grid.cc:343
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
Definition: Vector.cc:434
virtual bool projection_yields_grid()
Definition: Grid.cc:611
Map_iter map_begin()
Returns an iterator referencing the first Map vector.
Definition: Grid.cc:479
virtual int dimension_size(Dim_iter i, bool constrained=false)
Returns the size of the dimension.
Definition: Array.cc:556
virtual BaseType * ptr_duplicate()
Definition: Grid.cc:114
Map_iter get_map_iter(int i)
Definition: Grid.cc:517
virtual void add_var(BaseType *bt, Part part)
Definition: Grid.cc:218
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition: AttrTable.cc:409
virtual void transfer_attributes(AttrTable *at_container)
Definition: Grid.cc:559
virtual void clear_constraint()
Definition: Grid.cc:655
virtual AttrTable * get_attr_table(const string &name)
Get an attribute container.
Definition: AttrTable.cc:606
virtual Type type() const
Returns the type of the class instance.
Definition: BaseType.cc:310
std::vector< dimension >::iterator Dim_iter
Definition: Array.h:204
virtual BaseType * ptr_duplicate()
Definition: Array.cc:174
virtual int dimension_stride(Dim_iter i, bool constrained=false)
Returns the stride value of the constraint.
Definition: Array.cc:638
Holds the Grid data type.
Definition: Grid.h:122
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
virtual void print_val(ostream &out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition: Grid.cc:819
virtual Array * add_map(Array *p_new_map, bool add_copy)
Definition: Grid.cc:409
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 dump(ostream &strm) const
dumps information about this object
Definition: Constructor.cc:827
virtual bool is_dap2_only_type()
Definition: Grid.cc:200
virtual Attr_iter attr_begin()
Definition: AttrTable.cc:710
virtual BaseType * ptr_duplicate()=0
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)
Print an ASCII representation of the variable structure.
Definition: Grid.cc:672
virtual int dimension_start(Dim_iter i, bool constrained=false)
Return the start index of a dimension.
Definition: Array.cc:589
virtual AttrTable & get_attr_table()
Definition: BaseType.cc:527
virtual unsigned int append_attr(const string &name, const string &type, const string &value)
Add an attribute to the table.
Definition: AttrTable.cc:306
The basic data type for the DODS DAP types.
Definition: BaseType.h:117
virtual AttrType get_attr_type(const string &name)
Get the type of an attribute.
Definition: AttrTable.cc:620
Dim_iter dim_begin()
Definition: Array.cc:510
virtual string type_name() const
Returns the type of the class instance as a string.
Definition: BaseType.cc:324
virtual bool check_semantics(string &msg, bool all=false)
Return true if this Grid is well formed.
Definition: Grid.cc:856
virtual vector< string > * get_attr_vector(const string &name)
Get a vector-valued attribute.
Definition: AttrTable.cc:652
BaseType * array_var()
Returns the Grid Array.
Definition: Grid.cc:455
void add_map(D4Map *map)
Definition: D4Maps.h:115
virtual BaseType * transform_to_dap4(D4Group *root, Constructor *container)
DAP2 to DAP4 transform.
Definition: Grid.cc:148
virtual void transfer_attributes(AttrTable *at)
Definition: BaseType.cc:589
A multidimensional array of identical data types.
Definition: Array.h:112
virtual void print_val(ostream &out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition: Array.cc:1106
virtual bool send_p()
Should this variable be sent?
Definition: BaseType.cc:499
virtual void print_xml_writer(XMLWriter &xml, bool constrained=false)
Definition: Grid.cc:766
Grid(const string &n)
The Grid constructor.
Definition: Grid.cc:84
string id2www(string in, const string &allowable)
Definition: escaping.cc:153
virtual void clear_constraint()
Clears the projection; add each projected dimension explicitly using add_constraint.
Definition: Array.cc:429
virtual bool check_semantics(string &msg, bool all=false)
Compare an object&#39;s current state with the semantics of its type.
Definition: BaseType.cc:1130
virtual BaseType * transform_to_dap4(D4Group *root, Constructor *container)
DAP2 to DAP4 transform.
Definition: BaseType.cc:215