libdap
Updated for version 3.17.0
|
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 // Implementation for the Error class. 00033 00034 00035 #include "config.h" 00036 00037 #include <cstdio> 00038 #include <cassert> 00039 00040 #include "Error.h" 00041 #include "parser.h" 00042 #include "InternalErr.h" 00043 #include "debug.h" 00044 00045 using namespace std; 00046 00047 // Glue routines declared in Error.lex 00048 extern void Error_switch_to_buffer(void *new_buffer); 00049 extern void Error_delete_buffer(void * buffer); 00050 extern void *Error_buffer(FILE *fp); 00051 00052 //extern void Errorrestart(FILE *yyin); // defined in Error.tab.c 00053 extern int Errorparse(libdap::parser_arg *arg); 00054 00055 namespace libdap { 00056 00057 // There are two entries for 'cannot read file' because of an error made 00058 // when the message was first added to this class. 00059 static const char *err_messages[] = { 00060 "Undefined error", 00061 "Unknown error", 00062 "Internal error", 00063 "No such file", 00064 "No such variable", 00065 "Malformed expression", 00066 "No authorization", 00067 "Cannot read file", 00068 "Not Implemented", 00069 "" 00070 }; 00071 00074 Error::Error() : _error_code(undefined_error), _error_message("") 00075 {} 00076 00086 Error::Error(ErrorCode ec, string msg) 00087 : _error_code(ec), _error_message(msg) 00088 {} 00089 00095 Error::Error(string msg) 00096 : _error_code(unknown_error), _error_message(msg) 00097 {} 00098 00099 Error::Error(const Error ©_from) 00100 : _error_code(copy_from._error_code), 00101 _error_message(copy_from._error_message) 00102 { 00103 } 00104 00105 Error::~Error() 00106 { 00107 } 00108 00109 Error & 00110 Error::operator=(const Error &rhs) 00111 { 00112 assert(OK()); 00113 00114 if (&rhs == this) // are they identical? 00115 return *this; 00116 else { 00117 _error_code = rhs._error_code; 00118 _error_message = rhs._error_message; 00119 00120 assert(this->OK()); 00121 00122 return *this; 00123 } 00124 } 00125 00132 bool 00133 Error::OK() const 00134 { 00135 // The object is empty - users cannot make these, but this class can! 00136 bool empty = ((_error_code == undefined_error) 00137 && (_error_message.empty())); 00138 00139 // Just a message - the program part is null. 00140 bool message = ((_error_code != undefined_error) 00141 && (!_error_message.empty())); 00142 00143 DBG(cerr << "empty: " << empty << ", message: " << message << endl); 00144 return empty || message; 00145 } 00146 00155 bool 00156 Error::parse(FILE *fp) 00157 { 00158 if (!fp) 00159 throw InternalErr(__FILE__, __LINE__, "Null input stream"); 00160 00161 void *buffer = Error_buffer(fp); 00162 Error_switch_to_buffer(buffer); 00163 00164 parser_arg arg(this); 00165 00166 bool status; 00167 try { 00168 status = Errorparse(&arg) == 0; 00169 Error_delete_buffer(buffer); 00170 } 00171 catch (Error &e) { 00172 Error_delete_buffer(buffer); 00173 throw InternalErr(__FILE__, __LINE__, e.get_error_message()); 00174 } 00175 00176 // STATUS is the result of the parser function; if a recoverable error 00177 // was found it will be true but arg.status() will be false. 00178 // I'm throwing an InternalErr here since Error objects are generated by 00179 // the core; they should always parse! 9/21/2000 jhrg 00180 if (!status || !arg.status()) 00181 throw InternalErr(__FILE__, __LINE__, "Error parsing error object!"); 00182 else 00183 return OK(); // Check object consistency 00184 } 00185 00186 00197 void 00198 Error::print(FILE *out) const 00199 { 00200 assert(OK()); 00201 00202 fprintf(out, "Error {\n") ; 00203 00204 fprintf(out, " code = %d;\n", static_cast<int>(_error_code)) ; 00205 00206 // If the error message is wrapped in double quotes, print it, else, add 00207 // wrapping double quotes. 00208 if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"') 00209 fprintf(out, " message = %s;\n", _error_message.c_str()) ; 00210 else 00211 fprintf(out, " message = \"%s\";\n", _error_message.c_str()) ; 00212 00213 fprintf(out, "};\n") ; 00214 } 00215 00226 void 00227 Error::print(ostream &strm) const 00228 { 00229 assert(OK()); 00230 00231 strm << "Error {\n" ; 00232 00233 strm << " code = " << static_cast<int>(_error_code) << ";\n" ; 00234 00235 // If the error message is wrapped in double quotes, print it, else, add 00236 // wrapping double quotes. 00237 if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"') 00238 strm << " message = " << _error_message.c_str() << ";\n" ; 00239 else 00240 strm << " message = \"" << _error_message.c_str() << "\";\n" ; 00241 00242 strm << "};\n" ; 00243 } 00244 00246 ErrorCode 00247 Error::get_error_code() const 00248 { 00249 assert(OK()); 00250 return _error_code; 00251 } 00252 00259 void 00260 Error::set_error_code(ErrorCode ec) 00261 { 00262 _error_code = ec; 00263 // Added check to make sure that err_messages is not accessed beyond its 00264 // bounds. 02/02/04 jhrg 00265 if (_error_message.empty() 00266 && ec > undefined_error && ec <= cannot_read_file) { 00267 _error_message = err_messages[ec - undefined_error]; 00268 } 00269 else { 00270 _error_message = err_messages[0]; 00271 } 00272 } 00273 00275 string 00276 Error::get_error_message() const 00277 { 00278 assert(OK()); 00279 00280 return string(_error_message); 00281 } 00282 00284 void 00285 Error::set_error_message(string msg) 00286 { 00287 _error_message = msg; 00288 } 00289 00290 } // namespace libdap