libdap++  Updated for version 3.8.2
Grid.cc
Go to the documentation of this file.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 <functional>
41 #include <algorithm>
42 
43 #include "Grid.h"
44 #include "DDS.h"
45 #include "Array.h" // for downcasts
46 #include "util.h"
47 #include "InternalErr.h"
48 #include "escaping.h"
49 
50 #include "debug.h"
51 
52 using namespace std;
53 
54 namespace libdap {
55 
56 void
57 Grid::_duplicate(const Grid &s)
58 {
59  // Clear out any spurious vars in Constructor::_vars
60  _vars.clear(); // [mjohnson 10 Sep 2009]
61 
62  _array_var = s._array_var->ptr_duplicate();
63  _array_var->set_parent(this);
64  _vars.push_back(_array_var); // so the Constructor::Vars_Iter sees it [mjohnson 10 Sep 2009]
65 
66  Grid &cs = const_cast<Grid &>(s);
67 
68  for (Map_iter i = cs._map_vars.begin(); i != cs._map_vars.end(); i++) {
69  BaseType *btp = (*i)->ptr_duplicate();
70  btp->set_parent(this);
71  _map_vars.push_back(btp);
72  _vars.push_back(btp); // push all map vectors as weak refs into super::_vars which won't delete them [mjohnson 10 Sep 2009]
73  }
74 
75 }
76 
86 Grid::Grid(const string &n) : Constructor(n, dods_grid_c), _array_var(0)
87 {}
88 
100 Grid::Grid(const string &n, const string &d)
101  : Constructor(n, d, dods_grid_c), _array_var(0)
102 {}
103 
105 Grid::Grid(const Grid &rhs) : Constructor(rhs)
106 {
107  _duplicate(rhs);
108 }
109 
111 {
112  delete _array_var; _array_var = 0;
113 
114  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
115  BaseType *btp = *i ;
116  delete btp ; btp = 0;
117  }
118 }
119 
120 BaseType *
122 {
123  return new Grid(*this);
124 }
125 
126 Grid &
128 {
129  if (this == &rhs)
130  return *this;
131 
132  delete _array_var; _array_var = 0;
133 
134  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
135  BaseType *btp = *i ;
136  delete btp ;
137  }
138 
139  // this doesn't copy Constructor::_vars so...
140  dynamic_cast<Constructor &>(*this) = rhs;
141 
142  // we do it in here...
143  _duplicate(rhs);
144 
145  return *this;
146 }
147 
148 int
150 {
151  if (!leaves)
152  return _map_vars.size() + 1;
153  else {
154  int i = 0;
155  for (Map_iter j = _map_vars.begin(); j != _map_vars.end(); j++) {
156  j += (*j)->element_count(leaves);
157  }
158 
159  if (!get_array())
160  throw InternalErr(__FILE__, __LINE__, "No Grid arry!");
161 
162  i += get_array()->element_count(leaves);
163  return i;
164  }
165 }
166 
167 void
168 Grid::set_send_p(bool state)
169 {
170  _array_var->set_send_p(state);
171 
172  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
173  (*i)->set_send_p(state);
174  }
175 
176  BaseType::set_send_p(state);
177 }
178 
179 void
180 Grid::set_read_p(bool state)
181 {
182  _array_var->set_read_p(state);
183 
184  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
185  (*i)->set_read_p(state);
186  }
187 
188  BaseType::set_read_p(state);
189 }
190 
191 void
193 {
194  _array_var->set_in_selection(state);
195 
196  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
197  (*i)->set_in_selection(state);
198  }
199 
201 }
202 
203 unsigned int
205 {
206  unsigned int sz = _array_var->width();
207 
208  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
209  sz += (*i)->width();
210  }
211 
212  return sz;
213 }
214 
215 void
217 {
218  dds.timeout_on();
219 
220  if (!read_p())
221  read(); // read() throws Error and InternalErr
222 
223  dds.timeout_off();
224 
225  if (_array_var->send_p())
226  _array_var->intern_data(eval, dds);
227 
228  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
229  if ((*i)->send_p()) {
230  (*i)->intern_data(eval, dds);
231  }
232  }
233 }
234 
235 bool
237  Marshaller &m, bool ce_eval)
238 {
239  dds.timeout_on();
240 
241  // Re ticket 560: Get an object from eval that describes how to sample
242  // and rearrange the data, then perform those actions. Alternative:
243  // implement this as a selection function.
244 
245  if (!read_p())
246  read(); // read() throws Error and InternalErr
247 
248 #if EVAL
249  if (ce_eval && !eval.eval_selection(dds, dataset()))
250  return true;
251 #endif
252 
253  dds.timeout_off();
254 
255  if (_array_var->send_p())
256  _array_var->serialize(eval, dds, m, false);
257 
258  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
259  if ((*i)->send_p()) {
260  (*i)->serialize(eval, dds, m, false);
261  }
262  }
263 
264  return true;
265 }
266 
267 bool
268 Grid::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
269 {
270  _array_var->deserialize(um, dds, reuse);
271 
272  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
273  (*i)->deserialize(um, dds, reuse);
274  }
275 
276  return false;
277 }
278 
286 unsigned int
287 Grid::val2buf(void *, bool)
288 {
289  return sizeof(Grid);
290 }
291 
295 unsigned int
297 {
298  return sizeof(Grid);
299 }
300 
301 BaseType *
302 Grid::var(const string &n, btp_stack &s)
303 {
304  return var(n, true, &s);
305 }
306 
311 BaseType *
312 Grid::var(const string &n, bool, btp_stack *s)
313 {
314  string name = www2id(n);
315 
316  if (_array_var->name() == name) {
317  if (s)
318  s->push(static_cast<BaseType *>(this));
319  return _array_var;
320  }
321 
322  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
323  if ((*i)->name() == name) {
324  if (s)
325  s->push(static_cast<BaseType *>(this));
326  return *i;
327  }
328  }
329 
330  return 0;
331 }
332 
345 void
347 {
348  if (!bt) {
349  throw InternalErr(__FILE__, __LINE__,
350  "Passing NULL pointer as variable to be added.");
351  }
352 
353  if (part == array && _array_var) {
354  // Avoid leaking memory... Function is add, not set, so it is an error to call again for the array part.
355  throw InternalErr(__FILE__, __LINE__, "Error: Grid::add_var called with part==Array, but the array was already set!");
356  }
357 
358  // Set to the clone of bt if we get that far.
359  BaseType* bt_clone = 0;
360 
361  switch (part) {
362 
363  case array: {
364  // Refactored to use new set_array ([mjohnson 11 nov 2009])
365  Array* p_arr = dynamic_cast<Array*>(bt);
366  // avoid obvious broken semantics
367  if (!p_arr) {
368  throw InternalErr(__FILE__, __LINE__,
369  "Grid::add_var(): with Part==array: object is not an Array!");
370  }
371  // Add it as a copy to preserve old semantics. This sets parent too.
372  bt_clone = p_arr->ptr_duplicate();
373  set_array(static_cast<Array*>(bt_clone));
374  }
375  break;
376 
377  case maps: {
378  bt_clone = bt->ptr_duplicate();
379  bt_clone->set_parent(this);
380  _map_vars.push_back(bt_clone);
381  }
382  break;
383 
384  default: {
385  if (!_array_var) {
386  // Refactored to use new set_array ([mjohnson 11 nov 2009])
387  Array* p_arr = dynamic_cast<Array*>(bt);
388  // avoid obvious broken semantics
389  if (!p_arr) {
390  throw InternalErr(__FILE__, __LINE__,
391  "Grid::add_var(): with Part==array: object is not an Array!");
392  }
393  // Add it as a copy to preserve old semantics. This sets parent too.
394  bt_clone = p_arr->ptr_duplicate();
395  set_array(static_cast<Array*>(bt_clone));
396  }
397  else {
398  bt_clone = bt->ptr_duplicate();
399  bt_clone->set_parent(this);
400  _map_vars.push_back(bt_clone);
401  }
402  }
403  break;
404  }// switch
405 
406  // if we get ehre without exception, add the cloned object to the superclass variable iterator
407  // mjohnson 10 Sep 2009
408  // Add it to the superclass _vars list so we can iterate on superclass vars
409  if (bt_clone) {
410  _vars.push_back(bt_clone);
411  }
412 }
413 
423 void
425 {
426  if (!p_new_arr) {
427  throw InternalErr(__FILE__, __LINE__,
428  "Grid::set_array(): Cannot set to null!");
429  }
430  // Make sure not same memory, this would be evil.
431  if (p_new_arr == _array_var) {
432  return;
433  }
434  // clean out any old array
435  delete _array_var; _array_var = 0;
436  // Set the new, with parent
437  _array_var = p_new_arr;
438  _array_var->set_parent(this);
439 }
440 
467 Array*
468 Grid::add_map(Array* p_new_map, bool add_as_copy)
469 {
470  if (!p_new_map) {
471  throw InternalErr(__FILE__, __LINE__,
472  "Grid::add_map(): cannot have p_new_map null!");
473  }
474 
475  if (add_as_copy) {
476  p_new_map = static_cast<Array*>(p_new_map->ptr_duplicate());
477  }
478 
479  p_new_map->set_parent(this);
480  _map_vars.push_back(p_new_map);
481  _vars.push_back(p_new_map); // allow superclass iter to work as well.
482 
483  // return the one that got put into the Grid.
484  return p_new_map;
485 }
486 
499 Array*
500 Grid::prepend_map(Array* p_new_map, bool add_copy)
501 {
502  if (add_copy)
503  {
504  p_new_map = static_cast<Array*>(p_new_map->ptr_duplicate());
505  }
506 
507  p_new_map->set_parent(this);
508  _map_vars.insert(_map_vars.begin(), p_new_map);
509  _vars.insert(_vars.begin(), p_new_map); // allow superclass iter to work as well.
510 
511  // return the one that got put into the Grid.
512  return p_new_map;
513 }
514 
518 BaseType *
520 {
521  return _array_var;
522 }
523 
527 Array *
529 {
530  Array *a = dynamic_cast<Array*>(_array_var);
531  if (a)
532  return a;
533  else
534  throw InternalErr(__FILE__, __LINE__, "bad Cast");
535 }
536 
540 {
541  return _map_vars.begin() ;
542 }
543 
548 {
549  return _map_vars.end() ;
550 }
551 
555 {
556  return _map_vars.rbegin() ;
557 }
558 
563 {
564  return _map_vars.rend() ;
565 }
566 
572 {
573  return _map_vars.begin() + i;
574 }
575 
591 int
592 Grid::components(bool constrained)
593 {
594  int comp;
595 
596  if (constrained) {
597  comp = _array_var->send_p() ? 1 : 0;
598 
599  for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
600  if ((*i)->send_p()) {
601  comp++;
602  }
603  }
604  }
605  else {
606  comp = 1 + _map_vars.size();
607  }
608 
609  return comp;
610 }
611 
613 {
614  AttrTable *at = at_container->get_attr_table(name());
615 
616  if (at) {
617  at->set_is_global_attribute(false);
618 
620 
621  Map_iter map = map_begin();
622  while (map != map_end()) {
623  (*map)->transfer_attributes(at);
624  map++;
625  }
626 
627  // Trick: If an attribute that's within the container 'at' still has its
628  // is_global_attribute property set, then it's not really a global attr
629  // but instead an attribute that belongs to this Grid.
630  AttrTable::Attr_iter at_p = at->attr_begin();
631  while (at_p != at->attr_end()) {
632  if (at->is_global_attribute(at_p)) {
633  if (at->get_attr_type(at_p) == Attr_container)
635  *at->get_attr_table(at_p)), at->get_name(at_p));
636  else
637  get_attr_table().append_attr(at->get_name(at_p),
638  at->get_type(at_p), at->get_attr_vector(at_p));
639  }
640 
641  at_p++;
642  }
643  }
644 }
645 
646 // When projected (using whatever the current constraint provides in the way
647 // of a projection), is the object still a Grid?
648 
665 bool
667 {
668  // For each dimension in the Array part, check the corresponding Map
669  // vector to make sure it is present in the projected Grid. If for each
670  // projected dimension in the Array component, there is a matching Map
671  // vector, then the Grid is valid.
672  bool valid = true;
673  Array *a = (Array *)_array_var;
674 
675  // Don't bother checking if the Array component is not included.
676  if (!a->send_p())
677  return false;
678 
679  // If only one part is being sent, it's clearly not a grid (it must be
680  // the array part of the Grid that's being sent (given that the above
681  // test passed and the array is being sent).
682  if (components(true) == 1)
683  return false;
684 
685  Array::Dim_iter d = a->dim_begin() ;
686  Map_iter m = map_begin() ;
687 
688  while (valid && d != a->dim_end() && m != map_end()) {
689  Array &map = dynamic_cast<Array&>(**m);
690  if (a->dimension_size(d, true) && map.send_p()) {
691  // Check the matching Map vector; the Map projection must equal
692  // the Array dimension projection
693  Array::Dim_iter fd = map.dim_begin(); // Maps have only one dim!
694  valid = map.dimension_start(fd, true) == a->dimension_start(d, true)
695  && map.dimension_stop(fd, true) == a->dimension_stop(d, true)
696  && map.dimension_stride(fd, true) == a->dimension_stride(d, true);
697  }
698  else {
699  valid = false;
700  }
701 
702  d++, m++;
703  }
704 
705  return valid;
706 }
707 
709 void
711 {
712  dynamic_cast<Array&>(*_array_var).clear_constraint();
713  for (Map_iter m = map_begin(); m != map_end(); ++m)
714  dynamic_cast<Array&>(*(*m)).clear_constraint();
715 }
716 
717 #if FILE_METHODS
718 void
719 Grid::print_decl(FILE *out, string space, bool print_semi,
720  bool constraint_info, bool constrained)
721 {
722  if (constrained && !send_p())
723  return;
724 
725  // The problem with the above is that if two Grids are projected and each
726  // contain one variable, say a map, and it happens to have the same name
727  // in each Grid, then without the enclosing Structures, the returned dataset
728  // has two variables with the same name at the same lexical level. So I'm
729  // removing the code above.
730  if (constrained && !projection_yields_grid()) {
731  fprintf(out, "%sStructure {\n", space.c_str()) ;
732 
733  _array_var->print_decl(out, space + " ", true, constraint_info,
734  constrained);
735 
736  for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
737  (*i)->print_decl(out, space + " ", true,
738  constraint_info, constrained);
739  }
740 
741  fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
742  }
743  else {
744  // The number of elements in the (projected) Grid must be such that
745  // we have a valid Grid object; send it as such.
746  fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
747 
748  fprintf(out, "%s Array:\n", space.c_str()) ;
749  _array_var->print_decl(out, space + " ", true, constraint_info,
750  constrained);
751 
752  fprintf(out, "%s Maps:\n", space.c_str()) ;
753  for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
754  (*i)->print_decl(out, space + " ", true,
755  constraint_info, constrained);
756  }
757 
758  fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
759  }
760 
761  if (constraint_info) {
762  if (send_p())
763  fprintf( out, ": Send True");
764  else
765  fprintf( out, ": Send False");
766  }
767 
768  if (print_semi)
769  fprintf(out, ";\n") ;
770 
771  return;
772 }
773 #endif
774 
775 void
776 Grid::print_decl(ostream &out, string space, bool print_semi,
777  bool constraint_info, bool constrained)
778 {
779  if (constrained && !send_p())
780  return;
781 
782  // See comment for the FILE* version of this method.
783  if (constrained && !projection_yields_grid()) {
784  out << space << "Structure {\n" ;
785 
786  _array_var->print_decl(out, space + " ", true, constraint_info,
787  constrained);
788 
789  for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
790  (*i)->print_decl(out, space + " ", true,
791  constraint_info, constrained);
792  }
793 
794  out << space << "} " << id2www(name()) ;
795  }
796  else {
797  // The number of elements in the (projected) Grid must be such that
798  // we have a valid Grid object; send it as such.
799  out << space << type_name() << " {\n" ;
800 
801  out << space << " Array:\n" ;
802  _array_var->print_decl(out, space + " ", true, constraint_info,
803  constrained);
804 
805  out << space << " Maps:\n" ;
806  for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
807  (*i)->print_decl(out, space + " ", true,
808  constraint_info, constrained);
809  }
810 
811  out << space << "} " << id2www(name()) ;
812  }
813 
814  if (constraint_info) {
815  if (send_p())
816  out << ": Send True";
817  else
818  out << ": Send False";
819  }
820 
821  if (print_semi)
822  out << ";\n" ;
823 
824  return;
825 }
826 
827 #if FILE_METHODS
828 class PrintMapField : public unary_function<BaseType *, void>
829 {
830  FILE *d_out;
831  string d_space;
832  bool d_constrained;
833  string d_tag;
834 public:
835  PrintMapField(FILE *o, string s, bool c, const string &t = "Map")
836  : d_out(o), d_space(s), d_constrained(c), d_tag(t)
837  {}
838 
839  void operator()(BaseType *btp)
840  {
841  Array *a = dynamic_cast<Array*>(btp);
842  if (!a)
843  throw InternalErr(__FILE__, __LINE__, "Expected an Array.");
844  a->print_xml_core(d_out, d_space, d_constrained, d_tag);
845  }
846 };
847 
848 void
849 Grid::print_xml(FILE *out, string space, bool constrained)
850 {
851  if (constrained && !send_p())
852  return;
853 
854  if (constrained && !projection_yields_grid()) {
855  fprintf(out, "%s<Structure", space.c_str());
856  if (!name().empty())
857  fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
858 
859  fprintf(out, ">\n");
860 
861  get_attr_table().print_xml(out, space + " ", constrained);
862 
863  get_array()->print_xml(out, space + " ", constrained);
864 
865  for_each(map_begin(), map_end(),
866  PrintMapField(out, space + " ", constrained, "Array"));
867 
868  fprintf(out, "%s</Structure>\n", space.c_str());
869  }
870  else {
871  // The number of elements in the (projected) Grid must be such that
872  // we have a valid Grid object; send it as such.
873  fprintf(out, "%s<Grid", space.c_str());
874  if (!name().empty())
875  fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
876 
877  fprintf(out, ">\n");
878 
879  get_attr_table().print_xml(out, space + " ", constrained);
880 
881  get_array()->print_xml(out, space + " ", constrained);
882 
883  for_each(map_begin(), map_end(),
884  PrintMapField(out, space + " ", constrained));
885 
886  fprintf(out, "%s</Grid>\n", space.c_str());
887  }
888 }
889 #endif
890 
891 class PrintMapFieldStrm : public unary_function<BaseType *, void>
892 {
893  ostream &d_out;
894  string d_space;
895  bool d_constrained;
896  string d_tag;
897 public:
898  PrintMapFieldStrm(ostream &o, string s, bool c, const string &t = "Map")
899  : d_out(o), d_space(s), d_constrained(c), d_tag(t)
900  {}
901 
902  void operator()(BaseType *btp)
903  {
904  Array *a = dynamic_cast<Array*>(btp);
905  if (!a)
906  throw InternalErr(__FILE__, __LINE__, "Expected an Array.");
907  a->print_xml_core(d_out, d_space, d_constrained, d_tag);
908  }
909 };
910 
911 void
912 Grid::print_xml(ostream &out, string space, bool constrained)
913 {
914  if (constrained && !send_p())
915  return;
916 
917  if (constrained && !projection_yields_grid()) {
918  out << space << "<Structure" ;
919  if (!name().empty())
920  out << " name=\"" << id2xml(name()) << "\"" ;
921 
922  out << ">\n" ;
923 
924  get_attr_table().print_xml(out, space + " ", constrained);
925 
926  get_array()->print_xml(out, space + " ", constrained);
927 
928  for_each(map_begin(), map_end(),
929  PrintMapFieldStrm(out, space + " ", constrained, "Array"));
930 
931  out << space << "</Structure>\n" ;
932  }
933  else {
934  // The number of elements in the (projected) Grid must be such that
935  // we have a valid Grid object; send it as such.
936  out << space << "<Grid" ;
937  if (!name().empty())
938  out << " name=\"" << id2xml(name()) << "\"" ;
939 
940  out << ">\n" ;
941 
942  get_attr_table().print_xml(out, space + " ", constrained);
943 
944  get_array()->print_xml(out, space + " ", constrained);
945 
946  for_each(map_begin(), map_end(),
947  PrintMapFieldStrm(out, space + " ", constrained));
948 
949  out << space << "</Grid>\n" ;
950  }
951 }
952 
953 #if FILE_METHODS
954 void
955 Grid::print_val(FILE *out, string space, bool print_decl_p)
956 {
957  if (print_decl_p) {
958  print_decl(out, space, false);
959  fprintf(out, " = ") ;
960  }
961 
962  // If we are printing a value on the client-side, projection_yields_grid
963  // should not be called since we don't *have* a projection without a
964  // contraint. I think that if we are here and send_p() is not true, then
965  // the value of this function should be ignored. 4/6/2000 jhrg
966  bool pyg = projection_yields_grid(); // hack 12/1/99 jhrg
967  if (pyg || !send_p())
968  fprintf(out, "{ Array: ") ;
969  else
970  fprintf(out, "{") ;
971  _array_var->print_val(out, "", false);
972  if (pyg || !send_p())
973  fprintf(out, " Maps: ") ;
974  for (Map_citer i = _map_vars.begin(); i != _map_vars.end();
975  i++, (void)(i != _map_vars.end() && fprintf(out, ", "))) {
976  (*i)->print_val(out, "", false);
977  }
978  fprintf(out, " }") ;
979 
980  if (print_decl_p)
981  fprintf(out, ";\n") ;
982 }
983 #endif
984 
985 void
986 Grid::print_val(ostream &out, string space, bool print_decl_p)
987 {
988  if (print_decl_p) {
989  print_decl(out, space, false);
990  out << " = " ;
991  }
992 
993  // If we are printing a value on the client-side, projection_yields_grid
994  // should not be called since we don't *have* a projection without a
995  // Constraint. I think that if we are here and send_p() is not true, then
996  // the value of this function should be ignored. 4/6/2000 jhrg
997  bool pyg = projection_yields_grid(); // hack 12/1/99 jhrg
998  if (pyg || !send_p())
999  out << "{ Array: " ;
1000  else
1001  out << "{" ;
1002  _array_var->print_val(out, "", false);
1003  if (pyg || !send_p())
1004  out << " Maps: " ;
1005  for (Map_citer i = _map_vars.begin(); i != _map_vars.end();
1006  i++, (void)(i != _map_vars.end() && out << ", ")) {
1007  (*i)->print_val(out, "", false);
1008  }
1009  out << " }" ;
1010 
1011  if (print_decl_p)
1012  out << ";\n" ;
1013 }
1014 
1015 // Grids have ugly semantics.
1016 
1021 bool
1022 Grid::check_semantics(string &msg, bool all)
1023 {
1024  if (!BaseType::check_semantics(msg))
1025  return false;
1026 
1027  msg = "";
1028 
1029  if (!_array_var) {
1030  msg += "Null grid base array in `" + name() + "'\n";
1031  return false;
1032  }
1033 
1034  // Is it an array?
1035  if (_array_var->type() != dods_array_c) {
1036  msg += "Grid `" + name() + "'s' member `" + _array_var->name() + "' must be an array\n";
1037  return false;
1038  }
1039 
1040  Array *av = (Array *)_array_var; // past test above, must be an array
1041 
1042  // Array must be of a simple_type.
1043  if (!av->var()->is_simple_type()) {
1044  msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
1045  return false;
1046  }
1047 
1048  // enough maps?
1049  if ((unsigned)_map_vars.size() != av->dimensions()) {
1050  msg += "The number of map variables for grid `" + this->name() + "' does not match the number of dimensions of `";
1051  msg += av->name() + "'\n";
1052  return false;
1053  }
1054 
1055  const string array_var_name = av->name();
1056  Array::Dim_iter asi = av->dim_begin() ;
1057  for (Map_iter mvi = _map_vars.begin();
1058  mvi != _map_vars.end(); mvi++, asi++) {
1059 
1060  BaseType *mv = *mvi;
1061 
1062  // check names
1063  if (array_var_name == mv->name()) {
1064  msg += "Grid map variable `" + mv->name() + "' conflicts with the grid array name in grid `" + name() + "'\n";
1065  return false;
1066  }
1067  // check types
1068  if (mv->type() != dods_array_c) {
1069  msg += "Grid map variable `" + mv->name() + "' is not an array\n";
1070  return false;
1071  }
1072 
1073  Array *mv_a = (Array *)mv; // downcast to (Array *)
1074 
1075  // Array must be of a simple_type.
1076  if (!mv_a->var()->is_simple_type()) {
1077  msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
1078  return false;
1079  }
1080 
1081  // check shape
1082  if (mv_a->dimensions() != 1) {// maps must have one dimension
1083  msg += "Grid map variable `" + mv_a->name() + "' must be only one dimension\n";
1084  return false;
1085  }
1086  // size of map must match corresponding array dimension
1087  Array::Dim_iter mv_asi = mv_a->dim_begin() ;
1088  int mv_a_size = mv_a->dimension_size(mv_asi) ;
1089  int av_size = av->dimension_size(asi) ;
1090  if (mv_a_size != av_size) {
1091  msg += "Grid map variable `" + mv_a->name() + "'s' size does not match the size of array variable '";
1092  msg += _array_var->name() + "'s' cooresponding dimension\n";
1093  return false;
1094  }
1095  }
1096 
1097  if (all) {
1098  if (!_array_var->check_semantics(msg, true))
1099  return false;
1100  for (Map_iter mvi = _map_vars.begin(); mvi != _map_vars.end(); mvi++) {
1101  if (!(*mvi)->check_semantics(msg, true)) {
1102  return false;
1103  }
1104  }
1105  }
1106 
1107  return true;
1108 }
1109 
1118 void
1119 Grid::dump(ostream &strm) const
1120 {
1121  strm << DapIndent::LMarg << "Grid::dump - ("
1122  << (void *)this << ")" << endl ;
1123  DapIndent::Indent() ;
1124  Constructor::dump(strm) ;
1125  if (_array_var) {
1126  strm << DapIndent::LMarg << "array var: " << endl ;
1127  DapIndent::Indent() ;
1128  _array_var->dump(strm) ;
1130  }
1131  else {
1132  strm << DapIndent::LMarg << "array var: null" << endl ;
1133  }
1134  strm << DapIndent::LMarg << "map var: " << endl ;
1135  DapIndent::Indent() ;
1136  Map_citer i = _map_vars.begin() ;
1137  Map_citer ie = _map_vars.end() ;
1138  for (; i != ie; i++) {
1139  (*i)->dump(strm) ;
1140  }
1143 }
1144 
1145 } // namespace libdap
1146 
std::vector< entry * >::iterator Attr_iter
Definition: AttrTable.h:233
virtual bool read()
Read data into a local buffer.
Definition: BaseType.cc:790
virtual bool read_p()
Has this variable been read?
Definition: BaseType.cc:444
string name() const
Returns the name of the class instance.
Definition: BaseType.cc:210
Map_riter map_rend()
Definition: Grid.cc:562
virtual void print_xml_core(FILE *out, string space, bool constrained, string tag)
Definition: Array.cc:640
static void UnIndent()
Definition: DapIndent.cc:49
abstract base class used to unmarshall/deserialize dap data objects
Definition: UnMarshaller.h:54
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.
Definition: BaseType.cc:853
virtual bool is_global_attribute() const
Definition: AttrTable.h:280
virtual Attr_iter attr_end()
Definition: AttrTable.cc:649
virtual unsigned int dimensions(bool constrained=false)
Return the total number of dimensions in the array.
Definition: Array.cc:362
virtual Array * prepend_map(Array *p_new_map, bool add_copy)
Definition: Grid.cc:500
Part
Names the parts of multi-section constructor data types.
Definition: BaseType.h:98
virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval=true)
Move data to the net.
Definition: Grid.cc:236
Contains the attributes for a dataset.
Definition: AttrTable.h:146
virtual unsigned int width()
Returns the size of the class instance data.
Definition: Grid.cc:204
Grid & operator=(const Grid &rhs)
Definition: Grid.cc:127
virtual string get_type(const string &name)
Get the type name of an attribute within this attribute table.
Definition: AttrTable.cc:543
virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse=false)=0
Receive data from the net.
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
Definition: Grid.cc:912
virtual void intern_data(ConstraintEvaluator &eval, DDS &dds)
Definition: BaseType.cc:799
virtual string get_name() const
Get the name of this attribute table.
Definition: AttrTable.cc:208
std::vector< BaseType * > _vars
Definition: Constructor.h:48
virtual void print_xml(FILE *out, string pad=" ", bool constrained=false)
Definition: AttrTable.cc:1209
string id2xml(string in, const string &not_allowed)
Definition: escaping.cc:266
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Grid.cc:1119
virtual bool serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval=true)=0
Move data to the net.
virtual unsigned int width()=0
Returns the size of the class instance data.
virtual void set_in_selection(bool state)
Definition: Grid.cc:192
virtual int element_count(bool leaves)
Count the members of constructor types.
Definition: Vector.cc:326
virtual void set_is_global_attribute(bool ga)
Definition: AttrTable.h:281
Map_iter map_end()
Definition: Grid.cc:547
virtual void set_send_p(bool state)
Definition: Grid.cc:168
void timeout_off()
Definition: DDS.cc:823
virtual unsigned int val2buf(void *buf, bool reuse=false)
Returns the size of the Grid type.
Definition: Grid.cc:287
virtual void set_in_selection(bool state)
Definition: BaseType.cc:625
stack< BaseType * > btp_stack
Definition: BaseType.h:214
virtual void set_parent(BaseType *parent)
Definition: BaseType.cc:638
A class for software fault reporting.
Definition: InternalErr.h:64
Dim_iter dim_end()
Definition: Array.cc:347
std::vector< BaseType * >::const_iterator Map_citer
Definition: Grid.h:139
virtual int components(bool constrained=false)
Returns the number of components in the Grid object.
Definition: Grid.cc:592
Map_riter map_rbegin()
Returns an iterator referencing the first Map vector.
Definition: Grid.cc:554
virtual void set_array(Array *p_new_arr)
Definition: Grid.cc:424
bool eval_selection(DDS &dds, const string &dataset)
Evaluate a boolean-valued constraint expression. This is main method for the evaluator ans is called ...
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
Definition: Vector.cc:383
virtual int element_count(bool leaves=false)
Count the members of constructor types.
Definition: Grid.cc:149
virtual bool projection_yields_grid()
Definition: Grid.cc:666
Map_iter map_begin()
Returns an iterator referencing the first Map vector.
Definition: Grid.cc:539
virtual int dimension_size(Dim_iter i, bool constrained=false)
Returns the size of the dimension.
Definition: Array.cc:390
virtual BaseType * ptr_duplicate()
Definition: Grid.cc:121
Map_iter get_map_iter(int i)
Definition: Grid.cc:571
virtual void intern_data(ConstraintEvaluator &eval, DDS &dds)
Definition: Grid.cc:216
virtual void set_send_p(bool state)
Definition: BaseType.cc:517
virtual void add_var(BaseType *bt, Part part)
Definition: Grid.cc:346
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition: AttrTable.cc:341
virtual void transfer_attributes(AttrTable *at_container)
Definition: Grid.cc:612
static void Indent()
Definition: DapIndent.cc:43
virtual void clear_constraint()
Definition: Grid.cc:710
virtual ~Grid()
Definition: Grid.cc:110
virtual AttrTable * get_attr_table(const string &name)
Get an attribute container.
Definition: AttrTable.cc:536
Type type() const
Returns the type of the class instance.
Definition: BaseType.cc:238
std::vector< dimension >::iterator Dim_iter
Definition: Array.h:152
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition: Grid.cc:180
virtual BaseType * ptr_duplicate()
Definition: Array.cc:138
virtual int dimension_stride(Dim_iter i, bool constrained=false)
Returns the stride value of the constraint.
Definition: Array.cc:472
virtual void set_read_p(bool state)
Sets the value of the read_p property.
Definition: BaseType.cc:483
Holds the Grid data type.
Definition: Grid.h:123
virtual void print_val(ostream &out, string space="", bool print_decl_p=true)
Prints the value of the variable.
Definition: Grid.cc:986
virtual Array * add_map(Array *p_new_map, bool add_copy)
Definition: Grid.cc:468
Array * get_array()
Returns the Grid Array. This method returns the array using an Array*, so no cast is required...
Definition: Grid.cc:528
std::vector< BaseType * >::iterator Map_iter
Definition: Grid.h:140
std::vector< BaseType * >::reverse_iterator Map_riter
Definition: Grid.h:141
virtual void dump(ostream &strm) const
dumps information about this object
Definition: Constructor.cc:502
virtual void print_xml(ostream &out, string space=" ", bool constrained=false)
Definition: Array.cc:600
virtual Attr_iter attr_begin()
Definition: AttrTable.cc:640
virtual BaseType * ptr_duplicate()=0
string www2id(const string &in, const string &escape, const string &except)
Definition: escaping.cc:214
virtual int dimension_stop(Dim_iter i, bool constrained=false)
Return the stop index of the constraint.
Definition: Array.cc:447
void timeout_on()
Definition: DDS.cc:815
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:776
Evaluate a constraint expression.
virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse=false)
Receive data from the net.
Definition: Grid.cc:268
static ostream & LMarg(ostream &strm)
Definition: DapIndent.cc:78
virtual int dimension_start(Dim_iter i, bool constrained=false)
Return the start index of a dimension.
Definition: Array.cc:423
virtual AttrTable & get_attr_table()
Definition: BaseType.cc:531
virtual BaseType * var(const string &n, bool exact=true, btp_stack *s=0)
Definition: Grid.cc:312
virtual unsigned int append_attr(const string &name, const string &type, const string &value)
Add an attribute to the table.
Definition: AttrTable.cc:239
The basic data type for the DODS DAP types.
Definition: BaseType.h:190
virtual AttrType get_attr_type(const string &name)
Get the type of an attribute.
Definition: AttrTable.cc:552
abstract base class used to marshal/serialize dap data objects
Definition: Marshaller.h:53
virtual unsigned int buf2val(void **val)
Definition: Grid.cc:296
Dim_iter dim_begin()
Definition: Array.cc:340
string type_name() const
Returns the type of the class instance as a string.
Definition: BaseType.cc:252
virtual bool check_semantics(string &msg, bool all=false)
Return true if this Grid is well formed.
Definition: Grid.cc:1022
virtual vector< string > * get_attr_vector(const string &name)
Get a vector-valued attribute.
Definition: AttrTable.cc:585
virtual bool is_simple_type()
Returns true if the instance is a numeric, string or URL type variable.
Definition: BaseType.cc:295
void _duplicate(const Grid &s)
Definition: Grid.cc:57
BaseType * array_var()
Returns the Grid Array.
Definition: Grid.cc:519
virtual void transfer_attributes(AttrTable *at)
Definition: BaseType.cc:571
A multidimensional array of identical data types.
Definition: Array.h:101
virtual bool send_p()
Should this variable be sent?
Definition: BaseType.cc:503
Grid(const string &n)
The Grid constructor.
Definition: Grid.cc:86
string id2www(string in, const string &allowable)
Definition: escaping.cc:151
string dataset() const
Returns the name of the dataset used to create this instance.
Definition: BaseType.cc:231
virtual void clear_constraint()
Clears the projection; add each projected dimension explicitly using add_constraint.
Definition: Array.cc:282
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:1036