#ifndef __RWERR_H__
#define __RWERR_H__

/*
 * Error definitions
 *
 * $Id: rwerr.h,v 3.6 1993/09/10 02:56:53 keffer Exp $
 *
 ****************************************************************************
 *
 * Rogue Wave Software, Inc.
 * P.O. Box 2328
 * Corvallis, OR 97339
 * Voice: (503) 754-3010	FAX: (503) 757-6650
 *
 * Copyright (C) 1989 - 1993.
 * This software is subject to copyright protection under the laws of
 * the United States and other countries.
 *
 ***************************************************************************
 *
 * $Log: rwerr.h,v $
 * Revision 3.6  1993/09/10  02:56:53  keffer
 * Switched RCS idents to avoid spurious diffs
 *
 * Revision 3.5  1993/08/19  20:36:00  randall
 * added public member functions to access private data for RWFileErr and RWStreamErr
 *
 * Revision 3.4  1993/08/16  17:17:21  randall
 * for Sun, must include exception.h for xmsg and xalloc declarations
 *
 * Revision 3.3  1993/07/30  03:23:42  jims
 * Port to MS C7
 *
 * Revision 3.2  1993/05/31  21:45:26  keffer
 * New messaging architecture for localization
 *
 * Revision 3.1  1993/05/18  00:38:35  keffer
 * Rewrote to use new messaging and exception handling facility.
 *
 */

#include "rw/defs.h"
#include <stdio.h>	/* Looking for FILE */
#ifndef RW_NO_XMSG
#  ifdef __SUNPRO_CC 
#    include <exception.h>
#  else
#    include <except.h>
#  endif
#endif

class RWExport RWMessage;

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                                RWxmsg                                //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef RW_NO_XMSG

// No host-supplied xmsg; we must supply it:
class RWExport RWxmsg
{
public:

  RWxmsg(const char*);
  RWxmsg(const RWMessage&);
  RWxmsg(const RWxmsg&);
  virtual ~RWxmsg();

  const char*	 why() const	{return msg_; }

  void 		raise();

protected:

  RWxmsg(const char*, RWBoolean doCopy);

private:

  void makeCopy(const char* str);
  const char* msg_;		// Message
  RWBoolean   doFree_;

};


#else


/*
 * Compiler-supplied xmsg available.
 * In this case, RWxmsg is merely an interface.
 */

class RWExport RWxmsg : public xmsg
{

public:

  RWxmsg(const char*);
  RWxmsg(const RWMessage&);

};

#endif

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                               RWxalloc                               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef RW_NO_XMSG

// No host-supplied xalloc; we must supply it:
class RWExport RWxalloc : public RWxmsg
{
public:

  RWxalloc(size_t size);

  size_t requested() const { return size_; }

private:

  size_t size_;

};

#else


/*
 * Compiler-supplied xalloc available.
 * In this case, RWxalloc is merely an interface.
 */

class RWExport RWxalloc : public xalloc
{
public:

  RWxalloc(size_t size);

};

#endif


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                            RWExternalErr                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

// For errors external to the library;
// these are errors the prudent programmer should expect,
// such as out-of-disk-space, file errors, and the like:

class RWExport RWExternalErr : public RWxmsg
{

public:

  RWExternalErr(const char*);
  RWExternalErr(const RWMessage&);

};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                              RWFileErr                               //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

// For errors involving a file descriptor:
class RWExport RWFileErr : public RWExternalErr
{

public:

  enum errType {unknown, seekErr, readErr, writeErr, openErr, closeErr};
  RWFileErr(const char*     , FILE*, errType type);
  RWFileErr(const RWMessage&, FILE*, errType type);

  FILE*   descriptor()          { return fd_;   }
  errType errorType()           { return type_; }

private:

  FILE* fd_;
  errType type_;
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                             RWStreamErr                              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

// For errors involving streams:
class RWExport RWStreamErr : public RWExternalErr
{

public:

  RWStreamErr(const char*     , ios&);
  RWStreamErr(const RWMessage&, ios&);

  ios&    errStream()          { return stream_; }

private:

  ios&    stream_;

};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                            RWInternalErr                             //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

// Logic errors are violated invariants, bounds errors,
// and the like.  

class RWExport RWInternalErr : public RWxmsg
{

public:

  RWInternalErr(const char*);
  RWInternalErr(const RWMessage&);

};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
//                             RWBoundsErr                              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class RWExport RWBoundsErr : public RWInternalErr
{

public:

  RWBoundsErr(const char*);
  RWBoundsErr(const RWMessage&);

};


#ifdef RW_NO_EXCEPTIONS
  // Compiler does not support exception handling:
  extern void rwexport RWThrow( const RWxmsg&        );
  extern void rwexport RWThrow( const RWxalloc&      );
  extern void rwexport RWThrow( const RWExternalErr& );
  extern void rwexport RWThrow( const RWFileErr&     );
  extern void rwexport RWThrow( const RWStreamErr&   );
  extern void rwexport RWThrow( const RWInternalErr& );
  extern void rwexport RWThrow( const RWBoundsErr&   );
  typedef void (rwfar *rwErrHandler)(const RWxmsg&);
  rwErrHandler rwexport rwSetErrHandler(rwErrHandler);
// Use extra parens to skirt MS C7 bug as documented in MS Problem ID: C9301003
# define RWTHROW(a) (RWThrow(a))
#else
  // Compiler supports exception handling:
# define RWTHROW(a) throw a
#endif


#endif /* __RWERR_H__ */
