libdap++  Updated for version 3.14.0
DDS.cc
Go to the documentation of this file.
1 // -*- mode: c++; c-basic-offset:4 -*-
2 
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5 
6 // Copyright (c) 2002,2003 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24 
25 // (c) COPYRIGHT URI/MIT 1994-1999
26 // Please read the full copyright statement in the file COPYRIGHT_URI.
27 //
28 // Authors:
29 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
30 
31 //
32 // jhrg 9/7/94
33 
34 #include "config.h"
35 
36 #include <cstdio>
37 #include <cmath>
38 #include <sys/types.h>
39 
40 #ifdef WIN32
41 #include <io.h>
42 #include <process.h>
43 #include <fstream>
44 #else
45 #include <unistd.h> // for alarm and dup
46 #include <sys/wait.h>
47 #endif
48 
49 #include <iostream>
50 #include <sstream>
51 #include <algorithm>
52 #include <functional>
53 
54 //#define DODS_DEBUG
55 //#define DODS_DEBUG2
56 
57 #include "GNURegex.h"
58 
59 #include "DAS.h"
60 #include "Clause.h"
61 #include "Error.h"
62 #include "InternalErr.h"
63 #include "Keywords2.h"
64 
65 #include "parser.h"
66 #include "debug.h"
67 #include "util.h"
68 
69 #include "Byte.h"
70 #include "Int16.h"
71 #include "UInt16.h"
72 #include "Int32.h"
73 #include "UInt32.h"
74 #include "Float32.h"
75 #include "Float64.h"
76 #include "Str.h"
77 #include "Url.h"
78 #include "Array.h"
79 #include "Structure.h"
80 #include "Sequence.h"
81 #include "Grid.h"
82 
83 #include "escaping.h"
84 
95 const string c_xml_xsi = "http://www.w3.org/2001/XMLSchema-instance";
96 const string c_xml_namespace = "http://www.w3.org/XML/1998/namespace";
97 
98 const string grddl_transformation_dap32 = "http://xml.opendap.org/transforms/ddxToRdfTriples.xsl";
99 
100 const string c_default_dap20_schema_location = "http://xml.opendap.org/dap/dap2.xsd";
101 const string c_default_dap32_schema_location = "http://xml.opendap.org/dap/dap3.2.xsd";
102 const string c_default_dap40_schema_location = "http://xml.opendap.org/dap/dap4.0.xsd";
103 
104 const string c_dap20_namespace = "http://xml.opendap.org/ns/DAP2";
105 const string c_dap32_namespace = "http://xml.opendap.org/ns/DAP/3.2#";
106 const string c_dap40_namespace = "http://xml.opendap.org/ns/DAP/4.0#";
107 
121 using namespace std;
122 
123 int ddsparse(libdap::parser_arg *arg);
124 
125 // Glue for the DDS parser defined in dds.lex
126 void dds_switch_to_buffer(void *new_buffer);
127 void dds_delete_buffer(void * buffer);
128 void *dds_buffer(FILE *fp);
129 
130 namespace libdap {
131 
132 void
133 DDS::duplicate(const DDS &dds)
134 {
135  DBG(cerr << "Entering DDS::duplicate... " <<endl);
136 #if 0
137  BaseTypeFactory *d_factory;
138 
139  string d_name; // The dataset d_name
140  string d_filename; // File d_name (or other OS identifier) for
141  string d_container_name; // d_name of container structure
142  Structure *d_container; // current container for container d_name
143  // dataset or part of dataset.
144 
145  int d_dap_major; // The protocol major version number
146  int d_dap_minor; // ... and minor version number
147  string d_dap_version; // String version of the protocol
148  string d_request_xml_base;
149  string d_namespace;
150 
151  AttrTable d_attr; // Global attributes.
152 
153  vector<BaseType *> vars; // Variables at the top level
154 
155  int d_timeout; // alarm time in seconds. If greater than
156  // zero, raise the alarm signal if more than
157  // d_timeout seconds are spent reading data.
158  Keywords d_keywords; // Holds keywords parsed from the CE
159 
160  long d_max_response_size; // In bytes
161 #endif
162 
163  d_factory = dds.d_factory;
164 
165  d_name = dds.d_name;
166  d_filename = dds.d_filename;
167  d_container_name = dds.d_container_name;
168  d_container = dds.d_container;
169 
170  d_dap_major = dds.d_dap_major;
171  d_dap_minor = dds.d_dap_minor;
172 
173  d_dap_version = dds.d_dap_version; // String version of the protocol
174  d_request_xml_base = dds.d_request_xml_base;
175  d_namespace = dds.d_namespace;
176 
177  d_attr = dds.d_attr;
178 
179  DDS &dds_tmp = const_cast<DDS &>(dds);
180 
181  // copy the things pointed to by the list, not just the pointers
182  for (Vars_iter i = dds_tmp.var_begin(); i != dds_tmp.var_end(); i++) {
183  add_var(*i); // add_var() dups the BaseType.
184  }
185 
186  d_timeout = dds.d_timeout;
187 
188  d_keywords = dds.d_keywords; // value copy; Keywords contains no pointers
189 
190  d_max_response_size = dds.d_max_response_size;
191 }
192 
193 //FIXME says 3.2 when it's 2.0
206 DDS::DDS(BaseTypeFactory *factory, const string &name)
207  : d_factory(factory), d_name(name), d_container_name(""), d_container(0),
208  d_request_xml_base(""),
209  d_timeout(0), d_keywords(), d_max_response_size(0)
210 {
211  DBG(cerr << "Building a DDS for the default version (3.2)" << endl);
212 
213  // This method sets a number of values, including those returned by
214  // get_protocol_major(), ..., get_namespace().
215  set_dap_version("2.0");
216 }
217 
233 DDS::DDS(BaseTypeFactory *factory, const string &name, const string &version)
234  : d_factory(factory), d_name(name), d_container_name(""), d_container(0),
235  d_request_xml_base(""),
236  d_timeout(0), d_keywords(), d_max_response_size(0)
237 {
238  DBG(cerr << "Building a DDS for version: " << version << endl);
239 
240  // This method sets a number of values, including those returned by
241  // get_protocol_major(), ..., get_namespace().
242  set_dap_version(version);
243 }
244 
246 DDS::DDS(const DDS &rhs) : DapObj()
247 {
248  DBG(cerr << "Entering DDS(const DDS &rhs) ..." << endl);
249  duplicate(rhs);
250  DBG(cerr << " bye." << endl);
251 }
252 
254 {
255  // delete all the variables in this DDS
256  for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
257  BaseType *btp = *i ;
258  delete btp ; btp = 0;
259  }
260 }
261 
262 DDS &
263 DDS::operator=(const DDS &rhs)
264 {
265  DBG(cerr << "Entering DDS::operator= ..." << endl);
266  if (this == &rhs)
267  return *this;
268 
269  duplicate(rhs);
270 
271  DBG(cerr << " bye." << endl);
272  return *this;
273 }
274 
289 {
290  // If there is a container set in the DDS then check the container from
291  // the DAS. If they are not the same container, then throw an exception
292  // (should be working on the same container). If the container does not
293  // exist in the DAS, then throw an exception
294  if (d_container && das->container_name() != d_container_name)
295  throw InternalErr(__FILE__, __LINE__,
296  "Error transferring attributes: working on a container in dds, but not das");
297 
298  // Give each variable a chance to claim its attributes.
299  AttrTable *top = das->get_top_level_attributes();
300 
301  for (DDS::Vars_iter i = var_begin(), e = var_end(); i != e; i++) {
302  (*i)->transfer_attributes(top);
303  }
304 #if 0
305  Vars_iter var = var_begin();
306  while (var != var_end()) {
307  try {
308  DBG(cerr << "Processing the attributes for: " << (*var)->d_name() << " a " << (*var)->type_name() << endl);
309  (*var)->transfer_attributes(top);
310  var++;
311  }
312  catch (Error &e) {
313  DBG(cerr << "Got this exception: " << e.get_error_message() << endl);
314  var++;
315  throw e;
316  }
317  }
318 #endif
319  // Now we transfer all of the attributes still marked as global to the
320  // global container in the DDS.
321  for (AttrTable::Attr_iter i = top->attr_begin(), e = top->attr_end(); i != e; ++i) {
322  if ((*i)->type == Attr_container && (*i)->attributes->is_global_attribute()) {
323  // copy the source container so that the DAS passed in can be
324  // deleted after calling this method.
325  AttrTable *at = new AttrTable(*(*i)->attributes);
326  d_attr.append_container(at, at->get_name());
327  }
328  }
329 #if 0
330  AttrTable::Attr_iter at_cont_p = top_level->attr_begin();
331  while (at_cont_p != top_level->attr_end()) {
332  // In truth, all of the top level attributes should be containers, but
333  // this test handles the abnormal case where somehow someone makes a
334  // top level attribute that is not a container by silently dropping it.
335  if ((*at_cont_p)->type == Attr_container && (*at_cont_p)->attributes->is_global_attribute()) {
336  DBG(cerr << (*at_cont_p)->d_name << " is a global attribute." << endl);
337  // copy the source container so that the DAS passed in can be
338  // deleted after calling this method.
339  AttrTable *at = new AttrTable(*(*at_cont_p)->attributes);
340  d_attr.append_container(at, at->get_name());
341  }
342 
343  at_cont_p++;
344  }
345 #endif
346 }
347 
355 
357 string
359 {
360  return d_name;
361 }
362 
364 void
365 DDS::set_dataset_name(const string &n)
366 {
367  d_name = n;
368 }
369 
371 
373 AttrTable &
375 {
376  return d_attr;
377 }
378 
388 string
390 {
391  return d_filename;
392 }
393 
395 void
396 DDS::filename(const string &fn)
397 {
398  d_filename = fn;
399 }
401 
405 void
407 {
408  d_dap_major = p;
409 
410  // This works because regardless of the order set_dap_major and set_dap_minor
411  // are called, once they both are called, the value in the string is
412  // correct. I protect against negative numbers because that would be
413  // nonsensical.
414  if (d_dap_minor >= 0) {
415  ostringstream oss;
416  oss << d_dap_major << "." << d_dap_minor;
417  d_dap_version = oss.str();
418  }
419 }
420 
424 void
426 {
427  d_dap_minor = p;
428 
429  if (d_dap_major >= 0) {
430  ostringstream oss;
431  oss << d_dap_major << "." << d_dap_minor;
432  d_dap_version = oss.str();
433  }
434 }
435 
441 void
442 DDS::set_dap_version(const string &v /* = "2.0" */)
443 {
444  istringstream iss(v);
445 
446  int major = -1, minor = -1;
447  char dot;
448  if (!iss.eof() && !iss.fail())
449  iss >> major;
450  if (!iss.eof() && !iss.fail())
451  iss >> dot;
452  if (!iss.eof() && !iss.fail())
453  iss >> minor;
454 
455  if (major == -1 || minor == -1 or dot != '.')
456  throw InternalErr(__FILE__, __LINE__, "Could not parse dap version. Value given: " + v);
457 
458  d_dap_version = v;
459 
460  d_dap_major = major;
461  d_dap_minor = minor;
462 
463  // Now set the related XML constants. These might be overwritten if
464  // the DDS instance is being built from a document parse, but if it's
465  // being constructed by a server the code to generate the XML document
466  // needs these values to match the DAP version information.
467  switch (d_dap_major) {
468  case 2:
469  d_namespace = c_dap20_namespace;
470  break;
471  case 3:
472  d_namespace = c_dap32_namespace;
473  break;
474  case 4:
475  d_namespace = c_dap40_namespace;
476  break;
477  default:
478  throw InternalErr(__FILE__, __LINE__, "Unknown DAP version.");
479  }
480 }
481 
489 void
491 {
492  int major = floor(d);
493  int minor = (d-major)*10;
494 
495  DBG(cerr << "Major: " << major << ", Minor: " << minor << endl);
496 
497  ostringstream oss;
498  oss << major << "." << minor;
499 
500  set_dap_version(oss.str());
501 }
502 
512 string
514 {
515  return d_container_name;
516 }
517 
520 void
521 DDS::container_name(const string &cn)
522 {
523  // we want to search the DDS for the top level structure with the given
524  // d_name. Set the container to null so that we don't search some previous
525  // container.
526  d_container = 0 ;
527  if( !cn.empty() )
528  {
529  d_container = dynamic_cast<Structure *>( var( cn ) ) ;
530  if( !d_container )
531  {
532  // create a structure for this container. Calling add_var
533  // while_container is null will add the new structure to DDS and
534  // not some sub structure. Adding the new structure makes a copy
535  // of it. So after adding it, go get it and set d_container.
536  Structure *s = new Structure( cn ) ;
537  add_var( s ) ;
538  delete s ;
539  s = 0 ;
540  d_container = dynamic_cast<Structure *>( var( cn ) ) ;
541  }
542  }
543  d_container_name = cn;
544 
545 }
546 
548 Structure *
550 {
551  return d_container ;
552 }
553 
555 
566 int
567 DDS::get_request_size(bool constrained)
568 {
569  int w = 0;
570  for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
571  if (constrained) {
572  if ((*i)->send_p())
573  w += (*i)->width(constrained);
574  }
575  else {
576  w += (*i)->width(constrained);
577  }
578  }
579 
580  return w;
581 }
582 
589  if (!bt)
590  throw InternalErr(__FILE__, __LINE__, "Trying to add a BaseType object with a NULL pointer.");
591 #if 0
592  if (bt->is_dap4_only_type())
593  throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 DDS.");
594 #endif
595  DBG2(cerr << "In DDS::add_var(), bt's address is: " << bt << endl);
596 
597  BaseType *btp = bt->ptr_duplicate();
598  DBG2(cerr << "In DDS::add_var(), btp's address is: " << btp << endl);
599  if (d_container) {
600  // Mem leak fix [mjohnson nov 2009]
601  // Structure::add_var() creates ANOTHER copy.
602  d_container->add_var(bt);
603  // So we need to delete btp or else it leaks
604  delete btp;
605  btp = 0;
606  }
607  else {
608  vars.push_back(btp);
609  }
610 }
611 
614 void
616 {
617  if (!bt)
618  throw InternalErr(__FILE__, __LINE__, "Trying to add a BaseType object with a NULL pointer.");
619 #if 0
620  //FIXME There's no longer a DAP2 and DAP4 DDS
621  if (bt->is_dap4_only_type())
622  throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 DDS.");
623 #endif
624 
625  DBG2(cerr << "In DDS::add_var(), bt's address is: " << bt << endl);
626 
627  if (d_container) {
628  d_container->add_var_nocopy(bt);
629  }
630  else {
631  vars.push_back(bt);
632  }
633 }
634 
635 
642 void
643 DDS::del_var(const string &n)
644 {
645  if( d_container )
646  {
647  d_container->del_var( n ) ;
648  return ;
649  }
650 
651  for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
652  if ((*i)->name() == n) {
653  BaseType *bt = *i ;
654  vars.erase(i) ;
655  delete bt ; bt = 0;
656  return;
657  }
658  }
659 }
660 
665 void
667 {
668  if (i != vars.end()) {
669  BaseType *bt = *i ;
670  vars.erase(i) ;
671  delete bt ; bt = 0;
672  }
673 }
674 
681 void
683 {
684  for (Vars_iter i_tmp = i1; i_tmp != i2; i_tmp++) {
685  BaseType *bt = *i_tmp ;
686  delete bt ; bt = 0;
687  }
688  vars.erase(i1, i2) ;
689 }
690 
698 BaseType *
699 DDS::var(const string &n, BaseType::btp_stack &s)
700 {
701  return var(n, &s);
702 }
722 BaseType *
723 DDS::var(const string &n, BaseType::btp_stack *s)
724 {
725  string name = www2id(n);
726  if( d_container )
727  return d_container->var( name, false, s ) ;
728 
729  BaseType *v = exact_match(name, s);
730  if (v)
731  return v;
732 
733  return leaf_match(name, s);
734 }
735 
736 BaseType *
738 {
739  DBG(cerr << "DDS::leaf_match: Looking for " << n << endl);
740 
741  for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
742  BaseType *btp = *i;
743  DBG(cerr << "DDS::leaf_match: Looking for " << n << " in: " << btp->d_name() << endl);
744  // Look for the d_name in the dataset's top-level
745  if (btp->name() == n) {
746  DBG(cerr << "Found " << n << " in: " << btp->d_name() << endl);
747  return btp;
748  }
749 
750  if (btp->is_constructor_type()) {
751  BaseType *found = btp->var(n, false, s);
752  if (found) {
753  DBG(cerr << "Found " << n << " in: " << btp->d_name() << endl);
754  return found;
755  }
756  }
757 #if STRUCTURE_ARRAY_SYNTAX_OLD
758  if (btp->is_vector_type() && btp->var()->is_constructor_type()) {
759  s->push(btp);
760  BaseType *found = btp->var()->var(n, false, s);
761  if (found) {
762  DBG(cerr << "Found " << n << " in: " << btp->var()->d_name() << endl);
763  return found;
764  }
765  }
766 #endif
767  }
768 
769  return 0; // It is not here.
770 }
771 
772 BaseType *
773 DDS::exact_match(const string &name, BaseType::btp_stack *s)
774 {
775  for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
776  BaseType *btp = *i;
777  DBG2(cerr << "Looking for " << d_name << " in: " << btp << endl);
778  // Look for the d_name in the current ctor type or the top level
779  if (btp->name() == name) {
780  DBG2(cerr << "Found " << d_name << " in: " << btp << endl);
781  return btp;
782  }
783  }
784 
785  string::size_type dot_pos = name.find(".");
786  if (dot_pos != string::npos) {
787  string aggregate = name.substr(0, dot_pos);
788  string field = name.substr(dot_pos + 1);
789 
790  BaseType *agg_ptr = var(aggregate, s);
791  if (agg_ptr) {
792  DBG2(cerr << "Descending into " << agg_ptr->name() << endl);
793  return agg_ptr->var(field, true, s);
794  }
795  else
796  return 0; // qualified names must be *fully* qualified
797  }
798 
799  return 0; // It is not here.
800 }
801 
802 
807 {
808  return vars.begin();
809 }
810 
813 {
814  return vars.rbegin();
815 }
816 
819 {
820  return vars.end() ;
821 }
822 
825 {
826  return vars.rend() ;
827 }
828 
834 {
835  return vars.begin() + i;
836 }
837 
841 BaseType *
843 {
844  return *(vars.begin() + i);
845 }
846 
851 void
853 {
854 #if 0
855  if (ptr->is_dap4_only_type())
856  throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 DDS.");
857 #endif
858  vars.insert(i, ptr->ptr_duplicate());
859 }
860 
868 void
870 {
871 #if 0
872  if (ptr->is_dap4_only_type())
873  throw InternalErr(__FILE__, __LINE__, "Attempt to add a DAP4 type to a DAP2 DDS.");
874 #endif
875  vars.insert(i, ptr);
876 }
877 
879 int
881 {
882  return vars.size();
883 }
884 
885 void
887 {
888 #ifndef WIN32
889  alarm(d_timeout);
890 #endif
891 }
892 
893 void
895 {
896 #ifndef WIN32
897  d_timeout = alarm(0);
898 #endif
899 }
900 
901 void
903 {
904  // Has no effect under win32
905  d_timeout = t;
906 }
907 
908 int
910 {
911  // Has to effect under win32
912  return d_timeout;
913 }
914 
916 void
918 {
919  for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
920  if ((*i)->type() == dods_sequence_c)
921  dynamic_cast<Sequence&>(**i).set_leaf_sequence();
922  else if ((*i)->type() == dods_structure_c)
923  dynamic_cast<Structure&>(**i).set_leaf_sequence();
924  }
925 }
926 
928 void
929 DDS::parse(string fname)
930 {
931  FILE *in = fopen(fname.c_str(), "r");
932 
933  if (!in) {
934  throw Error(cannot_read_file, "Could not open: " + fname);
935  }
936 
937  try {
938  parse(in);
939  fclose(in);
940  }
941  catch (Error &e) {
942  fclose(in);
943  throw ;
944  }
945 }
946 
947 
949 void
950 DDS::parse(int fd)
951 {
952 #ifdef WIN32
953  FILE *in = fdopen(_dup(fd), "r");
954 #else
955  FILE *in = fdopen(dup(fd), "r");
956 #endif
957 
958  if (!in) {
959  throw InternalErr(__FILE__, __LINE__, "Could not access file.");
960  }
961 
962  try {
963  parse(in);
964  fclose(in);
965  }
966  catch (Error &e) {
967  fclose(in);
968  throw ;
969  }
970 }
971 
978 void
979 DDS::parse(FILE *in)
980 {
981  if (!in) {
982  throw InternalErr(__FILE__, __LINE__, "Null input stream.");
983  }
984 
985  void *buffer = dds_buffer(in);
986  dds_switch_to_buffer(buffer);
987 
988  parser_arg arg(this);
989 
990  bool status = ddsparse(&arg) == 0;
991 
992  dds_delete_buffer(buffer);
993 
994  DBG2(cout << "Status from parser: " << status << endl);
995 
996  // STATUS is the result of the parser function; if a recoverable error
997  // was found it will be true but arg.status() will be false.
998  if (!status || !arg.status()) {// Check parse result
999  if (arg.error())
1000  throw *arg.error();
1001  }
1002 }
1003 
1005 void
1006 DDS::print(FILE *out)
1007 {
1008  ostringstream oss;
1009  print(oss);
1010  fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
1011 }
1012 
1014 void
1015 DDS::print(ostream &out)
1016 {
1017  out << "Dataset {\n" ;
1018 
1019  for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
1020  (*i)->print_decl(out) ;
1021  }
1022 
1023  out << "} " << id2www(d_name) << ";\n" ;
1024 
1025  return ;
1026 }
1027 
1037 void
1038 DDS::print_das(ostream &out)
1039 {
1040  out << "Attributes {\n" ;
1041 
1042  d_attr.print(out, " ");
1043  for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
1044  (*i)->get_attr_table().print(out, " ");
1045  }
1046 
1047  out << "}\n" ;
1048 }
1049 
1060 void
1062 {
1063  ostringstream oss;
1064  print_constrained(oss);
1065  fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
1066 }
1067 
1078 void
1080 {
1081  out << "Dataset {\n" ;
1082 
1083  for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
1084  // for each variable, indent with four spaces, print a trailing
1085  // semicolon, do not print debugging information, print only
1086  // variables in the current projection.
1087  (*i)->print_decl(out, " ", true, false, true) ;
1088  }
1089 
1090  out << "} " << id2www(d_name) << ";\n" ;
1091 
1092  return;
1093 }
1094 
1106 void
1107 DDS::print_xml(FILE *out, bool constrained, const string &blob)
1108 {
1109  ostringstream oss;
1110  print_xml_writer(oss, constrained, blob);
1111  fwrite(oss.str().data(), 1, oss.str().length(), out);
1112 }
1113 
1125 void
1126 DDS::print_xml(ostream &out, bool constrained, const string &blob)
1127 {
1128  print_xml_writer(out, constrained, blob);
1129 }
1130 
1131 class VariablePrintXMLWriter : public unary_function<BaseType *, void>
1132 {
1133  XMLWriter &d_xml;
1134  bool d_constrained;
1135 public:
1136  VariablePrintXMLWriter(XMLWriter &xml, bool constrained)
1137  : d_xml(xml), d_constrained(constrained)
1138  {}
1139  void operator()(BaseType *bt)
1140  {
1141  bt->print_xml_writer(d_xml, d_constrained);
1142  }
1143 };
1144 
1161 void
1162 DDS::print_xml_writer(ostream &out, bool constrained, const string &blob)
1163 {
1164  XMLWriter xml(" ");
1165 
1166  // Stamp and repeat for these sections; trying to economize is makes it
1167  // even more confusing
1168  if (get_dap_major() >= 4) {
1169  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Group") < 0)
1170  throw InternalErr(__FILE__, __LINE__, "Could not write Group element");
1171  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
1172  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
1173 
1174  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "dapVersion", (const xmlChar*)get_dap_version().c_str()) < 0)
1175  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for dapVersion");
1176 
1177  if (!get_request_xml_base().empty()) {
1178  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:xml", (const xmlChar*)c_xml_namespace.c_str()) < 0)
1179  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:xml");
1180 
1181  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xml:base", (const xmlChar*)get_request_xml_base().c_str()) < 0)
1182  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xml:base");
1183  }
1184  if (!get_namespace().empty()) {
1185  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns", (const xmlChar*)get_namespace().c_str()) < 0)
1186  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns");
1187  }
1188  }
1189  else if (get_dap_major() == 3 && get_dap_minor() >= 2) {
1190  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Dataset") < 0)
1191  throw InternalErr(__FILE__, __LINE__, "Could not write Dataset element");
1192  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
1193  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
1194  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:xsi", (const xmlChar*)"http://www.w3.org/2001/XMLSchema-instance") < 0)
1195  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:xsi");
1196 
1197  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xsi:schemaLocation", (const xmlChar*)c_dap_32_n_sl.c_str()) < 0)
1198  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:schemaLocation");
1199 
1200  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:grddl", (const xmlChar*)"http://www.w3.org/2003/g/data-view#") < 0)
1201  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:grddl");
1202 
1203  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "grddl:transformation", (const xmlChar*)grddl_transformation_dap32.c_str()) < 0)
1204  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:transformation");
1205 
1206  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns", (const xmlChar*)c_dap32_namespace.c_str()) < 0)
1207  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns");
1208  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:dap", (const xmlChar*)c_dap32_namespace.c_str()) < 0)
1209  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:dap");
1210 
1211  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "dapVersion", (const xmlChar*)"3.2") < 0)
1212  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for dapVersion");
1213 
1214  if (!get_request_xml_base().empty()) {
1215  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:xml", (const xmlChar*)c_xml_namespace.c_str()) < 0)
1216  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:xml");
1217 
1218  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xml:base", (const xmlChar*)get_request_xml_base().c_str()) < 0)
1219  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xml:base");
1220  }
1221  }
1222  else { // dap2
1223  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Dataset") < 0)
1224  throw InternalErr(__FILE__, __LINE__, "Could not write Dataset element");
1225  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)d_name.c_str()) < 0)
1226  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for d_name");
1227  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:xsi", (const xmlChar*)"http://www.w3.org/2001/XMLSchema-instance") < 0)
1228  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:xsi");
1229 
1230  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns", (const xmlChar*)c_dap20_namespace.c_str()) < 0)
1231  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns");
1232 
1233  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xsi:schemaLocation", (const xmlChar*)c_dap_20_n_sl.c_str()) < 0)
1234  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:schemaLocation");
1235  }
1236 
1237  // Print the global attributes
1238  d_attr.print_xml_writer(xml);
1239 
1240  // Print each variable
1241  for_each(var_begin(), var_end(), VariablePrintXMLWriter(xml, constrained));
1242 
1243  // For DAP 3.2 and greater, use the new syntax and value. The 'blob' is
1244  // the CID of the MIME part that holds the data. For DAP2 (which includes
1245  // 3.0 and 3.1), the blob is an href. For DAP4, only write the CID if it's
1246  // given.
1247  if (get_dap_major() >= 4) {
1248  if (!blob.empty()) {
1249  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "blob") < 0)
1250  throw InternalErr(__FILE__, __LINE__, "Could not write blob element");
1251  string cid = "cid:" + blob;
1252  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "href", (const xmlChar*) cid.c_str()) < 0)
1253  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for d_name");
1254  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1255  throw InternalErr(__FILE__, __LINE__, "Could not end blob element");
1256  }
1257  }
1258  else if (get_dap_major() == 3 && get_dap_minor() >= 2) {
1259  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "blob") < 0)
1260  throw InternalErr(__FILE__, __LINE__, "Could not write blob element");
1261  string cid = "cid:" + blob;
1262  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "href", (const xmlChar*) cid.c_str()) < 0)
1263  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for d_name");
1264  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1265  throw InternalErr(__FILE__, __LINE__, "Could not end blob element");
1266  }
1267  else { // dap2
1268  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "dataBLOB") < 0)
1269  throw InternalErr(__FILE__, __LINE__, "Could not write dataBLOB element");
1270  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "href", (const xmlChar*) "") < 0)
1271  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for d_name");
1272  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1273  throw InternalErr(__FILE__, __LINE__, "Could not end dataBLOB element");
1274  }
1275 
1276  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1277  throw InternalErr(__FILE__, __LINE__, "Could not end Dataset element");
1278 
1279  out << xml.get_doc();// << ends;// << endl;
1280 }
1281 
1294 void
1295 DDS::print_dmr(ostream &out, bool constrained)
1296 {
1297  if (get_dap_major() < 4)
1298  throw InternalErr(__FILE__, __LINE__, "Tried to print a DMR with DAP major version less than 4");
1299 
1300  XMLWriter xml(" ");
1301 
1302  // DAP4 wraps a dataset in a top-level Group element.
1303  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "Group") < 0)
1304  throw InternalErr(__FILE__, __LINE__, "Could not write Group element");
1305 
1306  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:xml",
1307  (const xmlChar*) c_xml_namespace.c_str()) < 0)
1308  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:xml");
1309 
1310  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:xsi", (const xmlChar*) c_xml_xsi.c_str())
1311  < 0)
1312  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:xsi");
1313 
1314  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xsi:schemaLocation",
1315  (const xmlChar*) c_dap_40_n_sl.c_str()) < 0)
1316  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:schemaLocation");
1317 
1318  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns",
1319  (const xmlChar*) get_namespace().c_str()) < 0)
1320  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns");
1321 
1322  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "dapVersion",
1323  (const xmlChar*) get_dap_version().c_str()) < 0)
1324  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for dapVersion");
1325 
1326  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "dmrVersion", (const xmlChar*) get_dmr_version().c_str()) < 0)
1327  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for dapVersion");
1328 
1329  if (!get_request_xml_base().empty()) {
1330  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xml:base",
1331  (const xmlChar*) get_request_xml_base().c_str()) < 0)
1332  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xml:base");
1333  }
1334 
1335  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*) d_name.c_str()) < 0)
1336  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
1337 
1338  // Print the global attributes
1339  d_attr.print_xml_writer(xml);
1340 
1341  // Print each variable
1342  for_each(var_begin(), var_end(), VariablePrintXMLWriter(xml, constrained));
1343 
1344 #if 0
1345  // For DAP 3.2 and greater, use the new syntax and value. The 'blob' is
1346  // the CID of the MIME part that holds the data. For DAP2 (which includes
1347  // 3.0 and 3.1), the blob is an href. For DAP4, only write the CID if it's
1348  // given.
1349  if (get_dap_major() >= 4) {
1350  if (!blob.empty()) {
1351  if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) "blob") < 0)
1352  throw InternalErr(__FILE__, __LINE__, "Could not write blob element");
1353  string cid = "cid:" + blob;
1354  if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "href", (const xmlChar*) cid.c_str()) < 0)
1355  throw InternalErr(__FILE__, __LINE__, "Could not write attribute for d_name");
1356  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1357  throw InternalErr(__FILE__, __LINE__, "Could not end blob element");
1358  }
1359  }
1360 #endif
1361 
1362  if (xmlTextWriterEndElement(xml.get_writer()) < 0)
1363  throw InternalErr(__FILE__, __LINE__, "Could not end the top-level Group element");
1364 
1365  out << xml.get_doc();
1366 }
1367 
1368 // Used by DDS::send() when returning data from a function call.
1383 bool
1385 {
1386  // The dataset must have a d_name
1387  if (d_name == "") {
1388  cerr << "A dataset must have a d_name" << endl;
1389  return false;
1390  }
1391 
1392  string msg;
1393  if (!unique_names(vars, d_name, "Dataset", msg))
1394  return false;
1395 
1396  if (all)
1397  for (Vars_iter i = vars.begin(); i != vars.end(); i++)
1398  if (!(*i)->check_semantics(msg, true))
1399  return false;
1400 
1401  return true;
1402 }
1403 
1429 bool
1430 DDS::mark(const string &n, bool state)
1431 {
1432  // TODO use auto_ptr
1434 
1435  DBG2(cerr << "DDS::mark: Looking for " << n << endl);
1436 
1437  BaseType *variable = var(n, s);
1438  if (!variable) {
1439  DBG2(cerr << "Could not find variable " << n << endl);
1440  delete s; s = 0;
1441  return false;
1442  }
1443  variable->set_send_p(state);
1444 
1445  DBG2(cerr << "DDS::mark: Set variable " << variable->d_name()
1446  << " (a " << variable->type_name() << ")" << endl);
1447 
1448  // Now check the btp_stack and run BaseType::set_send_p for every
1449  // BaseType pointer on the stack. Using BaseType::set_send_p() will
1450  // set the property for a Constructor but not its contained variables
1451  // which preserves the semantics of projecting just one field.
1452  while (!s->empty()) {
1453  s->top()->BaseType::set_send_p(state);
1454 
1455  DBG2(cerr << "DDS::mark: Set variable " << s->top()->d_name()
1456  << " (a " << s->top()->type_name() << ")" << endl);
1457  // FIXME get_parent() hosed?
1458 #if 1
1459  string parent_name = (s->top()->get_parent()) ? s->top()->get_parent()->name(): "none";
1460  string parent_type = (s->top()->get_parent()) ? s->top()->get_parent()->type_name(): "none";
1461  DBG2(cerr << "DDS::mark: Parent variable " << parent_name << " (a " << parent_type << ")" << endl);
1462 #endif
1463  s->pop();
1464  }
1465 
1466  delete s ; s = 0;
1467 
1468  return true;
1469 }
1470 
1476 void
1477 DDS::mark_all(bool state)
1478 {
1479  for (Vars_iter i = vars.begin(); i != vars.end(); i++)
1480  (*i)->set_send_p(state);
1481 }
1482 
1490 void
1491 DDS::dump(ostream &strm) const
1492 {
1493  strm << DapIndent::LMarg << "DDS::dump - ("
1494  << (void *)this << ")" << endl ;
1495  DapIndent::Indent() ;
1496  strm << DapIndent::LMarg << "d_name: " << d_name << endl ;
1497  strm << DapIndent::LMarg << "filename: " << d_filename << endl ;
1498  strm << DapIndent::LMarg << "protocol major: " << d_dap_major << endl;
1499  strm << DapIndent::LMarg << "protocol minor: " << d_dap_minor << endl;
1500  strm << DapIndent::LMarg << "factory: " << (void *)d_factory << endl ;
1501 
1502  strm << DapIndent::LMarg << "global attributes:" << endl ;
1503  DapIndent::Indent() ;
1504  d_attr.dump(strm) ;
1506 
1507  if (vars.size()) {
1508  strm << DapIndent::LMarg << "vars:" << endl ;
1509  DapIndent::Indent() ;
1510  Vars_citer i = vars.begin() ;
1511  Vars_citer ie = vars.end() ;
1512  for (; i != ie; i++) {
1513  (*i)->dump(strm) ;
1514  }
1516  }
1517  else {
1518  strm << DapIndent::LMarg << "vars: none" << endl ;
1519  }
1520 
1522 }
1523 
1524 } // namespace libdap
std::vector< entry * >::iterator Attr_iter
Definition: AttrTable.h:229
const string c_dap32_namespace
Definition: DDS.cc:105
static void UnIndent()
Definition: DapIndent.cc:51
void print(FILE *out)
Print the entire DDS to the specified file.
Definition: DDS.cc:1006
const string c_dap_32_n_sl
Definition: DDS.cc:109
xmlTextWriterPtr get_writer()
Definition: XMLWriter.h:56
string filename() const
Definition: DDS.cc:389
virtual Attr_iter attr_end()
Definition: AttrTable.cc:718
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
void insert_var_nocopy(Vars_iter i, BaseType *ptr)
Definition: DDS.cc:869
const string c_dap20_namespace
Definition: DDS.cc:104
Contains the attributes for a dataset.
Definition: AttrTable.h:142
string get_dmr_version() const
Definition: DDS.h:269
void dds_delete_buffer(void *buffer)
Vars_iter get_vars_iter(int i)
Get an iterator.
Definition: DDS.cc:833
string get_error_message() const
Definition: Error.cc:275
const string c_default_dap32_schema_location
Definition: DDS.cc:101
BaseType * leaf_match(const string &name, BaseType::btp_stack *s=0)
Definition: DDS.cc:737
void insert_var(Vars_iter i, BaseType *ptr)
Insert a variable before the referenced element.
Definition: DDS.cc:852
Vars_iter var_begin()
Return an iterator to the first variable.
Definition: DDS.cc:806
const string c_default_dap40_schema_location
Definition: DDS.cc:102
string get_request_xml_base() const
Get the URL that will return this DDS/DDX/DataThing.
Definition: DDS.h:281
int ddsparse(libdap::parser_arg *arg)
void set_timeout(int t)
Definition: DDS.cc:902
DDS(BaseTypeFactory *factory, const string &name="")
Definition: DDS.cc:206
int get_request_size(bool constrained)
Get the estimated response size.
Definition: DDS.cc:567
BaseType * var(const string &n, BaseType::btp_stack &s)
Definition: DDS.cc:699
virtual void transfer_attributes(DAS *das)
Definition: DDS.cc:288
void print_xml(FILE *out, bool constrained, const string &blob="")
Definition: DDS.cc:1107
void print_xml_writer(XMLWriter &xml)
Definition: AttrTable.cc:1424
virtual void add_var_nocopy(BaseType *bt, Part part=nil)
Definition: Constructor.cc:407
virtual void print(FILE *out, string pad=" ", bool dereference=false)
Prints the attribute table.
Definition: AttrTable.cc:1242
std::vector< BaseType * >::const_iterator Vars_citer
Definition: DDS.h:218
void timeout_off()
Definition: DDS.cc:894
void print_xml_writer(ostream &out, bool constrained, const string &blob="")
Definition: DDS.cc:1162
void add_var_nocopy(BaseType *bt)
Adds the variable to the DDS.
Definition: DDS.cc:615
Holds a structure (aggregate) type.
Definition: Structure.h:83
Vars_riter var_rend()
Return a reverse iterator.
Definition: DDS.cc:824
virtual void add_var(BaseType *bt, Part part=nil)
Definition: Constructor.cc:382
virtual string get_name() const
Get the name of this attribute table.
Definition: AttrTable.cc:237
#define DBG2(x)
Definition: debug.h:73
int num_var()
Returns the number of variables in the DDS.
Definition: DDS.cc:880
std::vector< BaseType * >::reverse_iterator Vars_riter
Definition: DDS.h:220
stack< BaseType * > btp_stack
Definition: BaseType.h:149
bool mark(const string &name, bool state)
Mark the send_p flag of the named variable to state.
Definition: DDS.cc:1430
A class for software fault reporting.
Definition: InternalErr.h:64
void parse(string fname)
Parse a DDS from a file with the given d_name.
Definition: DDS.cc:929
DDS & operator=(const DDS &rhs)
Definition: DDS.cc:263
const string c_dap40_namespace
Definition: DDS.cc:106
const char * version
Definition: getdap.cc:60
virtual BaseType * var(const string &name="", bool exact_match=true, btp_stack *s=0)
Returns a pointer to a member of a constructor class.
Definition: BaseType.cc:664
#define DBG(x)
Definition: debug.h:58
string type_name() const
Returns the type of the class instance as a string.
Definition: BaseType.cc:320
string get_namespace() const
Get the namespace associated with the DDS - likely set only by DDX responses.
Definition: DDS.h:287
virtual ~DDS()
Definition: DDS.cc:253
virtual bool is_constructor_type() const
Returns true if the instance is a constructor (i.e., Structure, Sequence or Grid) type variable...
Definition: BaseType.cc:353
string get_dap_version() const
Definition: DDS.h:268
int get_dap_major() const
Get the DAP major version as sent by the client.
Definition: DDS.h:263
virtual void set_send_p(bool state)
Definition: BaseType.cc:498
void mark_all(bool state)
Definition: DDS.cc:1477
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition: AttrTable.cc:409
const char * get_doc()
Definition: XMLWriter.cc:105
static void Indent()
Definition: DapIndent.cc:45
#define cannot_read_file
Definition: Error.h:66
const string c_xml_namespace
Definition: DDS.cc:96
std::vector< BaseType * >::iterator Vars_iter
Definition: DDS.h:219
void print_das(ostream &out)
Definition: DDS.cc:1038
virtual bool is_vector_type() const
Returns true if the instance is a vector (i.e., array) type variable.
Definition: BaseType.cc:343
const string c_dap_40_n_sl
Definition: DDS.cc:110
void print_dmr(ostream &out, bool constrained)
Definition: DDS.cc:1295
virtual AttrTable & get_attr_table()
Definition: DDS.cc:374
BaseType * get_var_index(int i)
Get a variable.
Definition: DDS.cc:842
bool check_semantics(bool all=false)
Check the semantics of each of the variables represented in the DDS.
Definition: DDS.cc:1384
void * dds_buffer(FILE *fp)
Structure * container()
Definition: DDS.cc:549
Error * error()
Definition: parser.h:93
string container_name()
Definition: DDS.cc:513
void dds_switch_to_buffer(void *new_buffer)
string name() const
Returns the name of the class instance.
Definition: BaseType.cc:261
virtual AttrTable * get_top_level_attributes()
Returns the top most set of attributes.
Definition: DAS.h:143
virtual Attr_iter attr_begin()
Definition: AttrTable.cc:710
virtual BaseType * ptr_duplicate()=0
string www2id(const string &in, const string &escape, const string &except)
Definition: escaping.cc:220
void timeout_on()
Definition: DDS.cc:886
Vars_iter var_end()
Return an iterator.
Definition: DDS.cc:818
BaseType * exact_match(const string &name, BaseType::btp_stack *s=0)
Definition: DDS.cc:773
void tag_nested_sequences()
Traverse DDS, set Sequence leaf nodes.
Definition: DDS.cc:917
static ostream & LMarg(ostream &strm)
Definition: DapIndent.cc:80
const string c_default_dap20_schema_location
Definition: DDS.cc:100
void set_dap_minor(int p)
Definition: DDS.cc:425
void set_dataset_name(const string &n)
Definition: DDS.cc:365
The basic data type for the DODS DAP types.
Definition: BaseType.h:117
libdap base object for common functionality of libdap objects
Definition: DapObj.h:55
Pass parameters by reference to a parser.
Definition: parser.h:68
void del_var(const string &n)
Removes a variable from the DDS.
Definition: DDS.cc:643
bool unique_names(vector< BaseType * > l, const string &var_name, const string &type_name, string &msg)
Definition: util.cc:491
virtual void dump(ostream &strm) const
dumps information about this object
Definition: AttrTable.cc:1509
Vars_riter var_rbegin()
Return a reverse iterator.
Definition: DDS.cc:812
Hold attribute data for a DAP2 dataset.
Definition: DAS.h:121
const string grddl_transformation_dap32
Definition: DDS.cc:98
int get_dap_minor() const
Get the DAP minor version as sent by the client.
Definition: DDS.h:265
A class for error processing.
Definition: Error.h:90
string get_dataset_name() const
Definition: DDS.cc:358
void duplicate(const DDS &dds)
Definition: DDS.cc:133
void set_dap_major(int p)
Definition: DDS.cc:406
virtual void del_var(const string &name)
Definition: Constructor.cc:423
int get_timeout()
Definition: DDS.cc:909
void print_constrained(FILE *out)
Print a constrained DDS to the specified file.
Definition: DDS.cc:1061
virtual void dump(ostream &strm) const
dumps information about this object
Definition: DDS.cc:1491
virtual string container_name()
Returns the name of the current attribute container when multiple files used to build this DAS...
Definition: DAS.cc:98
void set_dap_version(const string &version_string="2.0")
Definition: DDS.cc:442
string id2www(string in, const string &allowable)
Definition: escaping.cc:153
void add_var(BaseType *bt)
Adds a copy of the variable to the DDS. Using the ptr_duplicate() method, perform a deep copy on the ...
Definition: DDS.cc:588
const string c_dap_20_n_sl
Definition: DDS.cc:108
const string c_xml_xsi
Definition: DDS.cc:95