//
//  Exception.h
//
//  Exception base class and ExceptionMsg class
//
//  David Burgess
//  March 2000
//

#ifndef QDOS_EXCEPTION_H
#define QDOS_EXCEPTION_H

#ifdef HAVE_SSTREAM_H
#include <sstream>
#else
#include <strstream>
#endif
#include <iostream>
#include <string>

#include <typeinfo>
#include "Std.h"

namespace QDOS {

typedef enum ExceptionStatus_e { E_NORM, E_FATAL, E_WARN } ExceptionStatus;

class ExceptionMsg : public string {
public:
  ExceptionMsg( void ) {;}
  ExceptionMsg( const ExceptionMsg& m ) : string(m) {;}
  ExceptionMsg( string m ) : string(m) {;}
  ExceptionMsg( const char* cs ) : string(cs) {;}
  
  ExceptionMsg& operator<<( const char *cs )
  {
    this->string::operator+=( string(cs) );
    return *this;  
  }
  ExceptionMsg& operator<<( const string& s )
  {
    this->string::operator+=( s );
    return *this;  
  }


// seems that this sometimes got wrong number of chars when
// concatenating const char* or string (hence the above explicit
// definitions
  template <class T> ExceptionMsg& operator<<( const T& t )
  {
    ostrstream ost;
    ost << t;
    this->string::operator+=( ost.str() );
    return *this;
  }
};

class Exception {
  ExceptionMsg _msg;
  ExceptionStatus _status;
public:
  Exception(void) : _msg(), _status(E_NORM) {;}
  Exception( ExceptionMsg m, ExceptionStatus s=E_NORM )
    : _status(s), _msg(m) {;}
  Exception( const Exception& e )
    : _status(e._status), _msg(e._msg) {;}
  virtual void print_msg(void) const
  { std::cout << _msg << endl; }
  const ExceptionMsg& msg(void) const { return _msg; }
  ExceptionMsg& msg(void) { return _msg; }
  ExceptionStatus status(void) { return _status; }
};

} // end namespace QDOS

#endif // #ifndef QDOS_EXCEPTION_H
