libdap  Updated for version 3.20.10
libdap4 is an implementation of OPeNDAP's DAP protocol.
DAS.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 // Methods for the class DAS - a class used to parse the dataset attribute
33 // structure.
34 //
35 // jhrg 7/25/94
36 
37 #include "config.h"
38 
39 #include <cstdio>
40 
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 
45 #ifdef WIN32
46 #include <io.h>
47 #endif
48 
49 #include <iostream>
50 #include <string>
51 
52 #include "DAS.h"
53 #include "AttrTable.h"
54 #include "Error.h"
55 #include "InternalErr.h"
56 #include "parser.h"
57 #include "escaping.h"
58 #include "debug.h"
59 #include "DapIndent.h"
60 
61 using std::cerr;
62 using std::endl;
63 
64 // Glue routines declared in das.lex
65 extern void das_switch_to_buffer(void *new_buffer);
66 extern void das_delete_buffer(void * buffer);
67 extern void *das_buffer(FILE *fp);
68 
69 //extern void dasrestart(FILE *yyin);
70 //extern int dasparse(void *arg); // defined in das.tab.c
71 extern int dasparse(libdap::parser_arg *arg); // defined in das.tab.c
72 
73 namespace libdap {
74 
75 void DAS::duplicate(const DAS &src)
76 {
77  // If the container field is set, perform a deep copy
78  if (src.d_container)
79  d_container = new AttrTable(*src.d_container);
80  else
81  d_container = 0;
82 
83  d_container_name = src.d_container_name;
84  d_attrs = src.d_attrs;
85 }
86 
87 DAS &DAS::operator=(const DAS &rhs)
88 {
89  if (this == &rhs)
90  return *this;
91  duplicate(rhs);
92  return *this;
93 }
94 
100 void DAS::container_name(const string &cn)
101 {
102  // We want to find a top level attribute table with the given name. So
103  // set d_container to null first so that we aren't searching some
104  // previous container
105  if (cn != d_container_name) {
106  d_container = 0;
107  if (!cn.empty()) {
108  d_container = get_table(cn);
109  if (!d_container) {
110  d_container = add_table(cn, new AttrTable);
111  }
112  }
113  d_container_name = cn;
114  }
115 }
116 
123 unsigned int DAS::get_size() const
124 {
125  if (d_container) {
126  return d_container->get_size();
127  }
128  return d_attrs.get_size();
129 }
130 
134 {
135  if (d_container) {
136  d_container->erase();
137  }
138  else {
139  d_attrs.erase();
140  }
141 }
142 
145 AttrTable::Attr_iter DAS::var_begin()
146 {
147  if (d_container) {
148  return d_container->attr_begin();
149  }
150  return d_attrs.attr_begin();
151 }
152 
156 AttrTable::Attr_iter DAS::var_end()
157 {
158  if (d_container) {
159  return d_container->attr_end();
160  }
161  return d_attrs.attr_end();
162 }
163 
166 string DAS::get_name(AttrTable::Attr_iter &i)
167 {
168  if (d_container) {
169  return d_container->get_name(i);
170  }
171  return d_attrs.get_name(i);
172 }
173 
176 AttrTable *
177 DAS::get_table(AttrTable::Attr_iter &i)
178 {
179  if (d_container) {
180  return d_container->get_attr_table(i);
181  }
182  return d_attrs.get_attr_table(i);
183 }
184 
187 AttrTable *
188 DAS::get_table(const string &name)
189 {
190  if (d_container) {
191  return d_container->get_attr_table(name);
192  }
193  return d_attrs.get_attr_table(name);
194 }
195 
197 
202 
206 AttrTable *
207 DAS::add_table( const string &name, AttrTable *at )
208 {
209  if (d_container) {
210  at->set_is_global_attribute(false);
211  return d_container->append_container(at, name);
212  }
213  return d_attrs.append_container( at, name ) ;
214 }
215 
217 
223 
224 
229 void
230 DAS::parse(string fname)
231 {
232  FILE *in = fopen(fname.c_str(), "r");
233 
234  if (!in) {
235  throw Error(cannot_read_file, "Could not open: " + fname);
236  }
237 
238  parse(in);
239 
240  int res = fclose(in);
241  if (res) {
242  DBG(cerr << "DAS::parse - Failed to close file " << (void *)in << endl ;) ;
243  }
244 }
245 
256 void
257 DAS::parse(int fd)
258 {
259 #ifdef WIN32
260  int new_fd = _dup(fd);
261 #else
262  int new_fd = dup(fd);
263 #endif
264 
265  if (new_fd < 0)
266  throw InternalErr(__FILE__, __LINE__, "Could not access file.");
267  FILE *in = fdopen(new_fd, "r");
268 
269  if (!in) {
270  throw InternalErr(__FILE__, __LINE__, "Could not access file.");
271  }
272 
273  parse(in);
274 
275  int res = fclose(in);
276  if (res) {
277  DBG(cerr << "DAS::parse(fd) - Failed to close " << (void *)in << endl ;) ;
278  }
279 }
280 
281 
282 
289 void
290 DAS::parse(FILE *in)
291 {
292  if (!in) {
293  throw InternalErr(__FILE__, __LINE__, "Null input stream.");
294  }
295 
296  void *buffer = das_buffer(in);
297  das_switch_to_buffer(buffer);
298 
299  parser_arg arg(this);
300 
301  //bool status = dasparse((void *) & arg) == 0;
302  bool status = dasparse(&arg) == 0;
303 
304  das_delete_buffer(buffer);
305 
306  // STATUS is the result of the parser function; if a recoverable error
307  // was found it will be true but arg.status() will be false.
308  if (!status || !arg.status()) {// Check parse result
309  if (arg.error())
310  throw *arg.error();
311  }
312 }
313 
315 
328 void
329 DAS::print(FILE *out, bool dereference)
330 {
331  fprintf(out, "Attributes {\n") ;
332 
333  d_attrs.print(out, " ", dereference);
334 
335  fprintf(out, "}\n") ;
336 }
337 
350 void
351 DAS::print(ostream &out, bool dereference)
352 {
353  out << "Attributes {\n" ;
354 
355  d_attrs.print(out, " ", dereference);
356 
357  out << "}\n" ;
358 }
359 
367 void DAS::dump(ostream &strm) const
368 {
369  strm << DapIndent::LMarg << "DAS::dump - (" << (void *) this << ")" << endl;
370  DapIndent::Indent();
371  if (d_container) {
372  strm << DapIndent::LMarg << "current container: " << d_container_name << endl;
373  }
374  else {
375  strm << DapIndent::LMarg << "current container: NONE" << endl;
376  }
377  d_attrs.dump(strm);
378  DapIndent::UnIndent();
379 }
380 
381 } // namespace libdap
382 
Contains the attributes for a dataset.
Definition: AttrTable.h:143
virtual AttrTable * append_container(const string &name)
Add a container to the attribute table.
Definition: AttrTable.cc:410
virtual AttrTable * get_attr_table(const string &name)
Get an attribute container.
Definition: AttrTable.cc:607
virtual Attr_iter attr_end()
Definition: AttrTable.cc:719
virtual Attr_iter attr_begin()
Definition: AttrTable.cc:711
virtual string get_name() const
Get the name of this attribute table.
Definition: AttrTable.cc:238
virtual void erase()
Erase the attribute table.
Definition: AttrTable.cc:1036
virtual void print(FILE *out, string pad=" ", bool dereference=false)
Prints the attribute table.
Definition: AttrTable.cc:1243
virtual unsigned int get_size() const
Get the number of entries in this attribute table.
Definition: AttrTable.cc:231
virtual void dump(ostream &strm) const
dumps information about this object
Definition: AttrTable.cc:1510
AttrTable::Attr_iter var_begin()
Returns a reference to the attribute table for the first variable.
Definition: DAS.cc:145
virtual unsigned int get_size() const
Returns the number of attributes in the current attribute table.
Definition: DAS.cc:123
virtual AttrTable * add_table(const string &name, AttrTable *at)
Adds a variable attribute table to the DAS or the current dataset container attribute table.
Definition: DAS.cc:207
virtual void print(FILE *out, bool dereference=false)
Definition: DAS.cc:329
virtual void dump(ostream &strm) const
dumps information about this object
Definition: DAS.cc:367
AttrTable::Attr_iter var_end()
Definition: DAS.cc:156
virtual void parse(string fname)
Reads a DAS from the named file.
Definition: DAS.cc:230
AttrTable * get_table(AttrTable::Attr_iter &i)
Returns the referenced variable attribute table.
Definition: DAS.cc:177
virtual void erase()
erase all attributes in this DAS
Definition: DAS.cc:133
string get_name(AttrTable::Attr_iter &i)
Returns the name of the referenced variable attribute table.
Definition: DAS.cc:166
virtual string container_name() const
Returns the name of the current attribute container when multiple files used to build this DAS.
Definition: DAS.h:149
A class for error processing.
Definition: Error.h:94
A class for software fault reporting.
Definition: InternalErr.h:65
top level DAP object to house generic methods
Definition: AlarmHandler.h:36
Pass parameters by reference to a parser.
Definition: parser.h:69