libdap  Updated for version 3.20.6
libdap4 is an implementation of OPeNDAP's DAP protocol.
Error.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 // Implementation for the Error class.
33 
34 
35 #include "config.h"
36 
37 #include <cstdio>
38 #include <cassert>
39 
40 #include "Error.h"
41 #include "parser.h"
42 #include "InternalErr.h"
43 #include "debug.h"
44 
45 using namespace std;
46 
47 // Glue routines declared in Error.lex
48 extern void Error_switch_to_buffer(void *new_buffer);
49 extern void Error_delete_buffer(void * buffer);
50 extern void *Error_buffer(FILE *fp);
51 
52 //extern void Errorrestart(FILE *yyin); // defined in Error.tab.c
53 extern int Errorparse(libdap::parser_arg *arg);
54 
55 namespace libdap {
56 
57 // There are two entries for 'cannot read file' because of an error made
58 // when the message was first added to this class.
59 static const char *err_messages[] = {
60  "Undefined error",
61  "Unknown error",
62  "Internal error",
63  "No such file",
64  "No such variable",
65  "Malformed expression",
66  "No authorization",
67  "Cannot read file",
68  "Not Implemented",
69  ""
70 };
71 
74 Error::Error() : exception(), _error_code(undefined_error), _error_message("")
75 {}
76 
86 Error::Error(ErrorCode ec, string msg)
87  : exception(), _error_code(ec), _error_message(msg)
88 {}
89 
95 Error::Error(string msg)
96  : exception(), _error_code(unknown_error), _error_message(msg)
97 {}
98 
99 Error::Error(const Error &copy_from)
100  : exception(), _error_code(copy_from._error_code), _error_message(copy_from._error_message)
101 {
102 }
103 
104 Error::~Error() throw()
105 {
106 }
107 
108 Error &
109 Error::operator=(const Error &rhs)
110 {
111  assert(OK());
112 
113  if (&rhs == this) // are they identical?
114  return *this;
115  else {
116  _error_code = rhs._error_code;
117  _error_message = rhs._error_message;
118 
119  assert(this->OK());
120 
121  return *this;
122  }
123 }
124 
131 bool
132 Error::OK() const
133 {
134  // The object is empty - users cannot make these, but this class can!
135  bool empty = ((_error_code == undefined_error)
136  && (_error_message.empty()));
137 
138  // Just a message - the program part is null.
139  bool message = ((_error_code != undefined_error)
140  && (!_error_message.empty()));
141 
142  DBG(cerr << "empty: " << empty << ", message: " << message << endl);
143  return empty || message;
144 }
145 
154 bool
155 Error::parse(FILE *fp)
156 {
157  if (!fp)
158  throw InternalErr(__FILE__, __LINE__, "Null input stream");
159 
160  void *buffer = Error_buffer(fp);
161  Error_switch_to_buffer(buffer);
162 
163  parser_arg arg(this);
164 
165  bool status;
166  try {
167  status = Errorparse(&arg) == 0;
168  Error_delete_buffer(buffer);
169  }
170  catch (Error &e) {
171  Error_delete_buffer(buffer);
172  throw InternalErr(__FILE__, __LINE__, e.get_error_message());
173  }
174 
175  // STATUS is the result of the parser function; if a recoverable error
176  // was found it will be true but arg.status() will be false.
177  // I'm throwing an InternalErr here since Error objects are generated by
178  // the core; they should always parse! 9/21/2000 jhrg
179  if (!status || !arg.status())
180  throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
181  else
182  return OK(); // Check object consistency
183 }
184 
185 
196 void
197 Error::print(FILE *out) const
198 {
199  assert(OK());
200 
201  fprintf(out, "Error {\n") ;
202 
203  fprintf(out, " code = %d;\n", static_cast<int>(_error_code)) ;
204 
205  // If the error message is wrapped in double quotes, print it, else, add
206  // wrapping double quotes.
207  if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
208  fprintf(out, " message = %s;\n", _error_message.c_str()) ;
209  else
210  fprintf(out, " message = \"%s\";\n", _error_message.c_str()) ;
211 
212  fprintf(out, "};\n") ;
213 }
214 
225 void
226 Error::print(ostream &strm) const
227 {
228  assert(OK());
229 
230  strm << "Error {\n" ;
231 
232  strm << " code = " << static_cast<int>(_error_code) << ";\n" ;
233 
234  // If the error message is wrapped in double quotes, print it, else, add
235  // wrapping double quotes.
236  if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
237  strm << " message = " << _error_message.c_str() << ";\n" ;
238  else
239  strm << " message = \"" << _error_message.c_str() << "\";\n" ;
240 
241  strm << "};\n" ;
242 }
243 
245 ErrorCode
247 {
248  assert(OK());
249  return _error_code;
250 }
251 
258 void
260 {
261  _error_code = ec;
262  // Added check to make sure that err_messages is not accessed beyond its
263  // bounds. 02/02/04 jhrg
264  if (_error_message.empty()
265  && ec > undefined_error && ec <= cannot_read_file) {
266  _error_message = err_messages[ec - undefined_error];
267  }
268  else {
269  _error_message = err_messages[0];
270  }
271 }
272 
274 string
276 {
277  assert(OK());
278 
279  return string(_error_message);
280 }
281 
283 void
285 {
286  _error_message = msg;
287 }
288 
289 } // namespace libdap
libdap::parser_arg
Pass parameters by reference to a parser.
Definition: parser.h:69
libdap::Error::parse
bool parse(FILE *fp)
Parse an Error object.
Definition: Error.cc:155
libdap::Error::set_error_message
void set_error_message(std::string msg="")
Definition: Error.cc:284
libdap::Error
A class for error processing.
Definition: Error.h:93
libdap::Error::print
void print(FILE *out) const
Definition: Error.cc:197
libdap::InternalErr
A class for software fault reporting.
Definition: InternalErr.h:65
libdap::Error::get_error_message
std::string get_error_message() const
Definition: Error.cc:275
libdap::Error::set_error_code
void set_error_code(ErrorCode ec=undefined_error)
Definition: Error.cc:259
libdap
top level DAP object to house generic methods
Definition: AlarmHandler.h:36
libdap::Error::Error
Error()
Definition: Error.cc:74
libdap::ErrorCode
int ErrorCode
An enumerated type for common errors.
Definition: Error.h:57
libdap::Error::OK
bool OK() const
Is the Error object valid?
Definition: Error.cc:132
libdap::Error::get_error_code
ErrorCode get_error_code() const
Definition: Error.cc:246