libdap  Updated for version 3.20.6
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 
92  duplicate(rhs);
93 
94  return *this;
95 }
96 
102 void DAS::container_name(const string &cn)
103 {
104  // We want to find a top level attribute table with the given name. So
105  // set d_container to null first so that we aren't searching some
106  // previous container
107  if (cn != d_container_name) {
108  d_container = 0;
109  if (!cn.empty()) {
110  d_container = get_table(cn);
111  if (!d_container) {
112  d_container = add_table(cn, new AttrTable);
113  }
114  }
115  d_container_name = cn;
116  }
117 }
118 
125 unsigned int DAS::get_size() const
126 {
127  if (d_container) {
128  return d_container->get_size();
129  }
130  return d_attrs.get_size();
131 }
132 
136 {
137  if (d_container) {
138  d_container->erase();
139  }
140  else {
141  d_attrs.erase();
142  }
143 }
144 
147 AttrTable::Attr_iter DAS::var_begin()
148 {
149  if (d_container) {
150  return d_container->attr_begin();
151  }
152  return d_attrs.attr_begin();
153 }
154 
158 AttrTable::Attr_iter DAS::var_end()
159 {
160  if (d_container) {
161  return d_container->attr_end();
162  }
163  return d_attrs.attr_end();
164 }
165 
168 string DAS::get_name(AttrTable::Attr_iter &i)
169 {
170  if (d_container) {
171  return d_container->get_name(i);
172  }
173  return d_attrs.get_name(i);
174 }
175 
178 AttrTable *
179 DAS::get_table(AttrTable::Attr_iter &i)
180 {
181  if (d_container) {
182  return d_container->get_attr_table(i);
183  }
184  return d_attrs.get_attr_table(i);
185 }
186 
189 AttrTable *
190 DAS::get_table(const string &name)
191 {
192  if (d_container) {
193  return d_container->get_attr_table(name);
194  }
195  return d_attrs.get_attr_table(name);
196 }
197 
199 
204 
208 AttrTable *
209 DAS::add_table( const string &name, AttrTable *at )
210 {
211  if (d_container) {
212  at->set_is_global_attribute(false);
213  return d_container->append_container(at, name);
214  }
215  return d_attrs.append_container( at, name ) ;
216 }
217 
219 
225 
226 
231 void
232 DAS::parse(string fname)
233 {
234  FILE *in = fopen(fname.c_str(), "r");
235 
236  if (!in) {
237  throw Error(cannot_read_file, "Could not open: " + fname);
238  }
239 
240  parse(in);
241 
242  int res = fclose(in);
243  if (res) {
244  DBG(cerr << "DAS::parse - Failed to close file " << (void *)in << endl ;) ;
245  }
246 }
247 
258 void
259 DAS::parse(int fd)
260 {
261 #ifdef WIN32
262  int new_fd = _dup(fd);
263 #else
264  int new_fd = dup(fd);
265 #endif
266 
267  if (new_fd < 0)
268  throw InternalErr(__FILE__, __LINE__, "Could not access file.");
269  FILE *in = fdopen(new_fd, "r");
270 
271  if (!in) {
272  throw InternalErr(__FILE__, __LINE__, "Could not access file.");
273  }
274 
275  parse(in);
276 
277  int res = fclose(in);
278  if (res) {
279  DBG(cerr << "DAS::parse(fd) - Failed to close " << (void *)in << endl ;) ;
280  }
281 }
282 
283 
284 
291 void
292 DAS::parse(FILE *in)
293 {
294  if (!in) {
295  throw InternalErr(__FILE__, __LINE__, "Null input stream.");
296  }
297 
298  void *buffer = das_buffer(in);
299  das_switch_to_buffer(buffer);
300 
301  parser_arg arg(this);
302 
303  //bool status = dasparse((void *) & arg) == 0;
304  bool status = dasparse(&arg) == 0;
305 
306  das_delete_buffer(buffer);
307 
308  // STATUS is the result of the parser function; if a recoverable error
309  // was found it will be true but arg.status() will be false.
310  if (!status || !arg.status()) {// Check parse result
311  if (arg.error())
312  throw *arg.error();
313  }
314 }
315 
317 
330 void
331 DAS::print(FILE *out, bool dereference)
332 {
333  fprintf(out, "Attributes {\n") ;
334 
335  d_attrs.print(out, " ", dereference);
336 
337  fprintf(out, "}\n") ;
338 }
339 
352 void
353 DAS::print(ostream &out, bool dereference)
354 {
355  out << "Attributes {\n" ;
356 
357  d_attrs.print(out, " ", dereference);
358 
359  out << "}\n" ;
360 }
361 
369 void DAS::dump(ostream &strm) const
370 {
371  strm << DapIndent::LMarg << "DAS::dump - (" << (void *) this << ")" << endl;
372  DapIndent::Indent();
373  if (d_container) {
374  strm << DapIndent::LMarg << "current container: " << d_container_name << endl;
375  }
376  else {
377  strm << DapIndent::LMarg << "current container: NONE" << endl;
378  }
379  d_attrs.dump(strm);
380  DapIndent::UnIndent();
381 }
382 
383 } // namespace libdap
384 
AttrTable * get_table(AttrTable::Attr_iter &i)
Returns the referenced variable attribute table.
Definition: DAS.cc:179
virtual Attr_iter attr_end()
Definition: AttrTable.cc:719
Contains the attributes for a dataset.
Definition: AttrTable.h:142
AttrTable::Attr_iter var_begin()
Returns a reference to the attribute table for the first variable.
Definition: DAS.cc:147
virtual string get_name() const
Get the name of this attribute table.
Definition: AttrTable.cc:238
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:209
virtual void print(FILE *out, string pad=" ", bool dereference=false)
Prints the attribute table.
Definition: AttrTable.cc:1243
virtual void print(FILE *out, bool dereference=false)
Definition: DAS.cc:331
top level DAP object to house generic methods
Definition: AISConnect.cc:30
A class for software fault reporting.
Definition: InternalErr.h:64
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
string get_name(AttrTable::Attr_iter &i)
Returns the name of the referenced variable attribute table.
Definition: DAS.cc:168
virtual void erase()
Erase the attribute table.
Definition: AttrTable.cc:1036
virtual unsigned int get_size() const
Returns the number of attributes in the current attribute table.
Definition: DAS.cc:125
virtual void erase()
erase all attributes in this DAS
Definition: DAS.cc:135
virtual Attr_iter attr_begin()
Definition: AttrTable.cc:711
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
AttrTable::Attr_iter var_end()
Definition: DAS.cc:158
virtual void parse(string fname)
Reads a DAS from the named file.
Definition: DAS.cc:232
Pass parameters by reference to a parser.
Definition: parser.h:68
virtual void dump(ostream &strm) const
dumps information about this object
Definition: DAS.cc:369
A class for error processing.
Definition: Error.h:92
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