libdap++ Updated for version 3.8.2
|
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 19624 2008-09-17 22:57:54Z 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 00090 /* 00091 DAS::DAS(AttrTable *attr, string name) 00092 { 00093 append_container(attr, www2id(name)); 00094 } 00095 */ 00096 00097 // FIXME: Need to create copy constructor and op=. 00098 00102 DAS::~DAS() 00103 {} 00104 00108 string 00109 DAS::container_name() 00110 { 00111 return _container_name ; 00112 } 00113 00119 void 00120 DAS::container_name( const string &cn ) 00121 { 00122 // We want to find a top level attribute table with the given name. So 00123 // set d_container to null first so that we aren't searching some 00124 // previous container 00125 if( cn != _container_name ) 00126 { 00127 d_container = 0 ; 00128 if( !cn.empty() ) 00129 { 00130 d_container = get_table( cn ) ; 00131 if( !d_container ) 00132 { 00133 d_container = add_table( cn, new AttrTable ) ; 00134 } 00135 } 00136 _container_name = cn; 00137 } 00138 } 00139 00145 AttrTable * 00146 DAS::container() 00147 { 00148 return d_container ; 00149 } 00150 00157 unsigned int 00158 DAS::get_size() const 00159 { 00160 if( d_container ) 00161 { 00162 return d_container->get_size() ; 00163 } 00164 return d_attrs.get_size() ; 00165 } 00166 00169 void 00170 DAS::erase() 00171 { 00172 if( d_container ) 00173 { 00174 d_container->erase() ; 00175 } 00176 else 00177 { 00178 d_attrs.erase() ; 00179 } 00180 } 00181 00184 AttrTable::Attr_iter 00185 DAS::var_begin() 00186 { 00187 if( d_container ) 00188 { 00189 return d_container->attr_begin() ; 00190 } 00191 return d_attrs.attr_begin() ; 00192 } 00193 00197 AttrTable::Attr_iter 00198 DAS::var_end() 00199 { 00200 if( d_container ) 00201 { 00202 return d_container->attr_end() ; 00203 } 00204 return d_attrs.attr_end() ; 00205 } 00206 00209 string 00210 DAS::get_name(AttrTable::Attr_iter &i) 00211 { 00212 if( d_container ) 00213 { 00214 return d_container->get_name( i ) ; 00215 } 00216 return d_attrs.get_name( i ) ; 00217 } 00218 00221 AttrTable * 00222 DAS::get_table(AttrTable::Attr_iter &i) 00223 { 00224 if( d_container ) 00225 { 00226 return d_container->get_attr_table( i ) ; 00227 } 00228 return d_attrs.get_attr_table( i ) ; 00229 } 00230 00233 AttrTable * 00234 DAS::get_table( const string &name ) 00235 { 00236 if( d_container ) 00237 { 00238 return d_container->get_attr_table( name ) ; 00239 } 00240 return d_attrs.get_attr_table( name ) ; 00241 } 00242 00244 00249 00253 AttrTable * 00254 DAS::add_table( const string &name, AttrTable *at ) 00255 { 00256 if( d_container ) 00257 { 00258 return d_container->append_container( at, name ) ; 00259 } 00260 return d_attrs.append_container( at, name ) ; 00261 } 00262 00264 00270 00271 00276 void 00277 DAS::parse(string fname) 00278 { 00279 FILE *in = fopen(fname.c_str(), "r"); 00280 00281 if (!in) { 00282 throw Error(cannot_read_file, "Could not open: " + fname); 00283 } 00284 00285 parse(in); 00286 00287 int res = fclose(in); 00288 if (res) { 00289 DBG(cerr << "DAS::parse - Failed to close file " << (void *)in << endl ;) ; 00290 } 00291 } 00292 00303 void 00304 DAS::parse(int fd) 00305 { 00306 #ifdef WIN32 00307 FILE *in = fdopen(_dup(fd), "r"); 00308 #else 00309 FILE *in = fdopen(dup(fd), "r"); 00310 #endif 00311 00312 if (!in) { 00313 throw InternalErr(__FILE__, __LINE__, "Could not access file."); 00314 } 00315 00316 parse(in); 00317 00318 int res = fclose(in); 00319 if (res) { 00320 DBG(cerr << "DAS::parse(fd) - Failed to close " << (void *)in << endl ;) ; 00321 } 00322 } 00323 00324 00325 00332 void 00333 DAS::parse(FILE *in) 00334 { 00335 if (!in) { 00336 throw InternalErr(__FILE__, __LINE__, "Null input stream."); 00337 } 00338 00339 void *buffer = das_buffer(in); 00340 das_switch_to_buffer(buffer); 00341 00342 parser_arg arg(this); 00343 00344 bool status = dasparse((void *) & arg) == 0; 00345 00346 das_delete_buffer(buffer); 00347 00348 // STATUS is the result of the parser function; if a recoverable error 00349 // was found it will be true but arg.status() will be false. 00350 if (!status || !arg.status()) {// Check parse result 00351 if (arg.error()) 00352 throw *arg.error(); 00353 } 00354 } 00355 00357 00370 void 00371 DAS::print(FILE *out, bool dereference) 00372 { 00373 fprintf(out, "Attributes {\n") ; 00374 00375 d_attrs.print(out, " ", dereference); 00376 00377 fprintf(out, "}\n") ; 00378 } 00379 00392 void 00393 DAS::print(ostream &out, bool dereference) 00394 { 00395 out << "Attributes {\n" ; 00396 00397 d_attrs.print(out, " ", dereference); 00398 00399 out << "}\n" ; 00400 } 00401 00409 void 00410 DAS::dump(ostream &strm) const 00411 { 00412 strm << DapIndent::LMarg << "DAS::dump - (" 00413 << (void *)this << ")" << endl ; 00414 DapIndent::Indent() ; 00415 if( d_container ) 00416 { 00417 strm << DapIndent::LMarg << "current container: " << _container_name 00418 << endl ; 00419 } 00420 else 00421 { 00422 strm << DapIndent::LMarg << "current container: NONE" << endl ; 00423 } 00424 d_attrs.dump(strm) ; 00425 DapIndent::UnIndent() ; 00426 } 00427 00428 } // namespace libdap 00429