libdap  Updated for version 3.17.0
DAS.cc
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2002,2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 // (c) COPYRIGHT URI/MIT 1994-1999
00027 // Please read the full copyright statement in the file COPYRIGHT_URI.
00028 //
00029 // Authors:
00030 //      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>
00031 
00032 // Methods for the class DAS - a class used to parse the dataset attribute
00033 // structure.
00034 //
00035 // jhrg 7/25/94
00036 
00037 #include "config.h"
00038 
00039 #include <cstdio>
00040 
00041 #ifdef HAVE_UNISTD_H
00042 #include <unistd.h>
00043 #endif
00044 
00045 #ifdef WIN32
00046 #include <io.h>
00047 #endif
00048 
00049 #include <iostream>
00050 #include <string>
00051 
00052 #include "DAS.h"
00053 #include "AttrTable.h"
00054 #include "Error.h"
00055 #include "InternalErr.h"
00056 #include "parser.h"
00057 #include "escaping.h"
00058 #include "debug.h"
00059 
00060 using std::cerr;
00061 using std::endl;
00062 
00063 // Glue routines declared in das.lex
00064 extern void das_switch_to_buffer(void *new_buffer);
00065 extern void das_delete_buffer(void * buffer);
00066 extern void *das_buffer(FILE *fp);
00067 
00068 //extern void dasrestart(FILE *yyin);
00069 //extern int dasparse(void *arg); // defined in das.tab.c
00070 extern int dasparse(libdap::parser_arg *arg); // defined in das.tab.c
00071 
00072 namespace libdap {
00073 
00076 DAS::DAS() : DapObj(), d_container( 0 )
00077 {}
00078 
00079 #if 0
00080 DAS::DAS(AttrTable *attr, string name)
00081 {
00082     append_container(attr, www2id(name));
00083 }
00084 #endif
00085 
00086 // FIXME: Need to create copy constructor and op=.
00087 
00091 DAS::~DAS()
00092 {}
00093 
00097 string
00098 DAS::container_name()
00099 {
00100     return _container_name ;
00101 }
00102 
00108 void DAS::container_name(const string &cn)
00109 {
00110     // We want to find a top level attribute table with the given name. So
00111     // set d_container to null first so that we aren't searching some
00112     // previous container
00113     if (cn != _container_name) {
00114         d_container = 0;
00115         if (!cn.empty()) {
00116             d_container = get_table(cn);
00117             if (!d_container) {
00118                 d_container = add_table(cn, new AttrTable);
00119             }
00120         }
00121         _container_name = cn;
00122     }
00123 }
00124 
00130 AttrTable *
00131 DAS::container()
00132 {
00133     return d_container ;
00134 }
00135 
00142 unsigned int DAS::get_size() const
00143 {
00144     if (d_container) {
00145         return d_container->get_size();
00146     }
00147     return d_attrs.get_size();
00148 }
00149 
00152 void DAS::erase()
00153 {
00154     if (d_container) {
00155         d_container->erase();
00156     }
00157     else {
00158         d_attrs.erase();
00159     }
00160 }
00161 
00164 AttrTable::Attr_iter DAS::var_begin()
00165 {
00166     if (d_container) {
00167         return d_container->attr_begin();
00168     }
00169     return d_attrs.attr_begin();
00170 }
00171 
00175 AttrTable::Attr_iter DAS::var_end()
00176 {
00177     if (d_container) {
00178         return d_container->attr_end();
00179     }
00180     return d_attrs.attr_end();
00181 }
00182 
00185 string DAS::get_name(AttrTable::Attr_iter &i)
00186 {
00187     if (d_container) {
00188         return d_container->get_name(i);
00189     }
00190     return d_attrs.get_name(i);
00191 }
00192 
00195 AttrTable *
00196 DAS::get_table(AttrTable::Attr_iter &i)
00197 {
00198     if (d_container) {
00199         return d_container->get_attr_table(i);
00200     }
00201     return d_attrs.get_attr_table(i);
00202 }
00203 
00206 AttrTable *
00207 DAS::get_table(const string &name)
00208 {
00209     if (d_container) {
00210         return d_container->get_attr_table(name);
00211     }
00212     return d_attrs.get_attr_table(name);
00213 }
00214 
00216 
00221 
00225 AttrTable *
00226 DAS::add_table( const string &name, AttrTable *at )
00227 {
00228     if (d_container) {
00229         at->set_is_global_attribute(false);
00230         return d_container->append_container(at, name);
00231     }
00232     return d_attrs.append_container( at, name ) ;
00233 }
00234 
00236 
00242 
00243 
00248 void
00249 DAS::parse(string fname)
00250 {
00251     FILE *in = fopen(fname.c_str(), "r");
00252 
00253     if (!in) {
00254         throw Error(cannot_read_file, "Could not open: " + fname);
00255     }
00256 
00257     parse(in);
00258 
00259     int res = fclose(in);
00260     if (res) {
00261         DBG(cerr << "DAS::parse - Failed to close file " << (void *)in << endl ;) ;
00262     }
00263 }
00264 
00275 void
00276 DAS::parse(int fd)
00277 {
00278 #ifdef WIN32
00279     int new_fd = _dup(fd);
00280 #else
00281     int new_fd = dup(fd);
00282 #endif
00283 
00284     if (new_fd < 0)
00285         throw InternalErr(__FILE__, __LINE__, "Could not access file.");
00286     FILE *in = fdopen(new_fd, "r");
00287 
00288     if (!in) {
00289         throw InternalErr(__FILE__, __LINE__, "Could not access file.");
00290     }
00291 
00292     parse(in);
00293 
00294     int res = fclose(in);
00295     if (res) {
00296         DBG(cerr << "DAS::parse(fd) - Failed to close " << (void *)in << endl ;) ;
00297     }
00298 }
00299 
00300 
00301 
00308 void
00309 DAS::parse(FILE *in)
00310 {
00311     if (!in) {
00312         throw InternalErr(__FILE__, __LINE__, "Null input stream.");
00313     }
00314 
00315     void *buffer = das_buffer(in);
00316     das_switch_to_buffer(buffer);
00317 
00318     parser_arg arg(this);
00319 
00320     //bool status = dasparse((void *) & arg) == 0;
00321     bool status = dasparse(&arg) == 0;
00322 
00323     das_delete_buffer(buffer);
00324 
00325     //  STATUS is the result of the parser function; if a recoverable error
00326     //  was found it will be true but arg.status() will be false.
00327     if (!status || !arg.status()) {// Check parse result
00328         if (arg.error())
00329             throw *arg.error();
00330     }
00331 }
00332 
00334 
00347 void
00348 DAS::print(FILE *out, bool dereference)
00349 {
00350     fprintf(out, "Attributes {\n") ;
00351 
00352     d_attrs.print(out, "    ", dereference);
00353 
00354     fprintf(out, "}\n") ;
00355 }
00356 
00369 void
00370 DAS::print(ostream &out, bool dereference)
00371 {
00372     out << "Attributes {\n" ;
00373 
00374     d_attrs.print(out, "    ", dereference);
00375 
00376     out << "}\n" ;
00377 }
00378 
00386 void
00387 DAS::dump(ostream &strm) const
00388 {
00389     strm << DapIndent::LMarg << "DAS::dump - ("
00390          << (void *)this << ")" << endl ;
00391     DapIndent::Indent() ;
00392     if( d_container )
00393     {
00394         strm << DapIndent::LMarg << "current container: " << _container_name
00395              << endl ;
00396     }
00397     else
00398     {
00399         strm << DapIndent::LMarg << "current container: NONE" << endl ;
00400     }
00401     d_attrs.dump(strm) ;
00402     DapIndent::UnIndent() ;
00403 }
00404 
00405 } // namespace libdap
00406