libdap++  Updated for version 3.8.2
DAS.cc
Go to the documentation of this file.
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 static char rcsid[] not_used =
00040     {"$Id: DAS.cc 24281 2011-03-09 00:22:31Z jimg $"
00041     };
00042 
00043 
00044 #include <cstdio>
00045 
00046 #ifdef HAVE_UNISTD_H
00047 #include <unistd.h>
00048 #endif
00049 
00050 #ifdef WIN32
00051 #include <io.h>
00052 #endif
00053 
00054 #include <iostream>
00055 #include <string>
00056 
00057 #include "DAS.h"
00058 #include "AttrTable.h"
00059 #include "Error.h"
00060 #include "InternalErr.h"
00061 #include "parser.h"
00062 #include "escaping.h"
00063 #include "debug.h"
00064 
00065 using std::cerr;
00066 using std::endl;
00067 
00068 // Glue routines declared in das.lex
00069 extern void das_switch_to_buffer(void *new_buffer);
00070 extern void das_delete_buffer(void * buffer);
00071 extern void *das_buffer(FILE *fp);
00072 
00073 extern void dasrestart(FILE *yyin);
00074 extern int dasparse(void *arg); // defined in das.tab.c
00075 
00076 namespace libdap {
00077 
00080 DAS::DAS() : DapObj(), d_container( 0 )
00081 {}
00082 
00083 #if 0
00084 DAS::DAS(AttrTable *attr, string name)
00085 {
00086     append_container(attr, www2id(name));
00087 }
00088 #endif
00089 
00090 // FIXME: Need to create copy constructor and op=.
00091 
00095 DAS::~DAS()
00096 {}
00097 
00101 string
00102 DAS::container_name()
00103 {
00104     return _container_name ;
00105 }
00106 
00112 void
00113 DAS::container_name( const string &cn )
00114 {
00115     // We want to find a top level attribute table with the given name. So
00116     // set d_container to null first so that we aren't searching some
00117     // previous container
00118     if( cn != _container_name )
00119     {
00120         d_container = 0 ;
00121         if( !cn.empty() )
00122         {
00123             d_container = get_table( cn ) ;
00124             if( !d_container )
00125             {
00126                 d_container = add_table( cn, new AttrTable ) ;
00127             }
00128         }
00129         _container_name = cn;
00130     }
00131 }
00132 
00138 AttrTable *
00139 DAS::container()
00140 {
00141     return d_container ;
00142 }
00143 
00150 unsigned int
00151 DAS::get_size() const
00152 {
00153     if( d_container )
00154     {
00155         return d_container->get_size() ;
00156     }
00157     return d_attrs.get_size() ;
00158 }
00159 
00162 void
00163 DAS::erase()
00164 {
00165     if( d_container )
00166     {
00167         d_container->erase() ;
00168     }
00169     else
00170     {
00171         d_attrs.erase() ;
00172     }
00173 }
00174 
00177 AttrTable::Attr_iter
00178 DAS::var_begin()
00179 {
00180     if( d_container )
00181     {
00182         return d_container->attr_begin() ;
00183     }
00184     return d_attrs.attr_begin() ;
00185 }
00186 
00190 AttrTable::Attr_iter
00191 DAS::var_end()
00192 {
00193     if( d_container )
00194     {
00195         return d_container->attr_end() ;
00196     }
00197     return d_attrs.attr_end() ;
00198 }
00199 
00202 string
00203 DAS::get_name(AttrTable::Attr_iter &i)
00204 {
00205     if( d_container )
00206     {
00207         return d_container->get_name( i ) ;
00208     }
00209     return d_attrs.get_name( i ) ;
00210 }
00211 
00214 AttrTable *
00215 DAS::get_table(AttrTable::Attr_iter &i)
00216 {
00217     if( d_container )
00218     {
00219         return d_container->get_attr_table( i ) ;
00220     }
00221     return d_attrs.get_attr_table( i ) ;
00222 }
00223 
00226 AttrTable *
00227 DAS::get_table( const string &name )
00228 {
00229     if( d_container )
00230     {
00231         return d_container->get_attr_table( name ) ;
00232     }
00233     return d_attrs.get_attr_table( name ) ;
00234 }
00235 
00237 
00242 
00246 AttrTable *
00247 DAS::add_table( const string &name, AttrTable *at )
00248 {
00249     if( d_container )
00250     {
00251         at->set_is_global_attribute( false ) ;
00252         return d_container->append_container( at, name ) ;
00253     }
00254     return d_attrs.append_container( at, name ) ;
00255 }
00256 
00258 
00264 
00265 
00270 void
00271 DAS::parse(string fname)
00272 {
00273     FILE *in = fopen(fname.c_str(), "r");
00274 
00275     if (!in) {
00276         throw Error(cannot_read_file, "Could not open: " + fname);
00277     }
00278 
00279     parse(in);
00280 
00281     int res = fclose(in);
00282     if (res) {
00283         DBG(cerr << "DAS::parse - Failed to close file " << (void *)in << endl ;) ;
00284     }
00285 }
00286 
00297 void
00298 DAS::parse(int fd)
00299 {
00300 #ifdef WIN32
00301     FILE *in = fdopen(_dup(fd), "r");
00302 #else
00303     FILE *in = fdopen(dup(fd), "r");
00304 #endif
00305 
00306     if (!in) {
00307         throw InternalErr(__FILE__, __LINE__, "Could not access file.");
00308     }
00309 
00310     parse(in);
00311 
00312     int res = fclose(in);
00313     if (res) {
00314         DBG(cerr << "DAS::parse(fd) - Failed to close " << (void *)in << endl ;) ;
00315     }
00316 }
00317 
00318 
00319 
00326 void
00327 DAS::parse(FILE *in)
00328 {
00329     if (!in) {
00330         throw InternalErr(__FILE__, __LINE__, "Null input stream.");
00331     }
00332 
00333     void *buffer = das_buffer(in);
00334     das_switch_to_buffer(buffer);
00335 
00336     parser_arg arg(this);
00337 
00338     bool status = dasparse((void *) & arg) == 0;
00339 
00340     das_delete_buffer(buffer);
00341 
00342     //  STATUS is the result of the parser function; if a recoverable error
00343     //  was found it will be true but arg.status() will be false.
00344     if (!status || !arg.status()) {// Check parse result
00345         if (arg.error())
00346             throw *arg.error();
00347     }
00348 }
00349 
00351 
00364 void
00365 DAS::print(FILE *out, bool dereference)
00366 {
00367     fprintf(out, "Attributes {\n") ;
00368 
00369     d_attrs.print(out, "    ", dereference);
00370 
00371     fprintf(out, "}\n") ;
00372 }
00373 
00386 void
00387 DAS::print(ostream &out, bool dereference)
00388 {
00389     out << "Attributes {\n" ;
00390 
00391     d_attrs.print(out, "    ", dereference);
00392 
00393     out << "}\n" ;
00394 }
00395 
00403 void
00404 DAS::dump(ostream &strm) const
00405 {
00406     strm << DapIndent::LMarg << "DAS::dump - ("
00407          << (void *)this << ")" << endl ;
00408     DapIndent::Indent() ;
00409     if( d_container )
00410     {
00411         strm << DapIndent::LMarg << "current container: " << _container_name
00412              << endl ;
00413     }
00414     else
00415     {
00416         strm << DapIndent::LMarg << "current container: NONE" << endl ;
00417     }
00418     d_attrs.dump(strm) ;
00419     DapIndent::UnIndent() ;
00420 }
00421 
00422 } // namespace libdap
00423