// -*- C++ -*-
#ifndef __STD_IOSBASE__
#define __STD_IOSBASE__
/***************************************************************************
 *
 * iosbase - Declarations for the Standard Library basic stream I/O
 *
 ***************************************************************************
 *    
 *  Copyright 2000 Compaq Computer Corporation
 *
 *  COMPAQ Registered in U.S. Patent and Trademark Office.
 *
 *  Confidential computer software. Valid license from Compaq required for
 *  possession, use or copying. Consistent with FAR 12.211 and 12.212,
 *  Commercial Computer Software, Computer Software Documentation, and
 *  Technical Data for Commercial Items are licensed to the U.S. Government
 *  under vendor's standard commercial license.
 *
 ****************************************************************************
 *
 * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
 * ALL RIGHTS RESERVED
 *
 * The software and information contained herein are proprietary to, and
 * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
 * intends to preserve as trade secrets such software and information.
 * This software is furnished pursuant to a written license agreement and
 * may be used, copied, transmitted, and stored only in accordance with
 * the terms of such license and with the inclusion of the above copyright
 * notice.  This software and information or any other copies thereof may
 * not be provided or otherwise made available to any other person.
 *
 * Notwithstanding any other lease or license that may pertain to, or
 * accompany the delivery of, this computer software and information, the
 * rights of the Government regarding its use, reproduction and disclosure
 * are as set forth in Section 52.227-19 of the FARS Computer
 * Software-Restricted Rights clause.
 * 
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
 * Technical Data and Computer Software clause at DFARS 252.227-7013.
 * Contractor/Manufacturer is Rogue Wave Software, Inc.,
 * P.O. Box 2328, Corvallis, Oregon 97339.
 *
 * This computer software and information is distributed with "restricted
 * rights."  Use, duplication or disclosure is subject to restrictions as
 * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
 * Computer Software-Restricted Rights (April 1985)."  If the Clause at
 * 18-52.227-74 "Rights in Data General" is specified in the contract,
 * then the "Alternate III" clause applies.
 *
 **************************************************************************/

#include <compnent.hxx>
#ifndef __USE_STD_IOSTREAM
#error "cannot include iosbase -- define __USE_STD_IOSTREAM to override default - see section 7.1.2 of the C++ Using Guide"
#else

#include <stdcomp>

#ifndef _RWSTD_NO_NEW_HEADER
#include <cstdio>
#include <cstdlib>
#include <cstring>
#ifndef _RWSTD_NO_WIDE_CHAR
#include <cwchar>
#ifndef _RWSTD_NO_WCTYPE_H
#include <cwctype>
#endif 
#endif // _RWSTD_NO_WIDE_CHAR
#include <cstddef>
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _RWSTD_NO_WIDE_CHAR
#ifndef _RWSTD_NO_WCHAR_H
#include <wchar.h>
#endif
#ifndef _RWSTD_NO_WCTYPE_H
#include <wctype.h>
#endif
#endif // _RWSTD_NO_WIDE_CHAR
#include <stddef.h>
#endif // _RWSTD_NO_NEW_HEADER

#include <stdmutex> 

#ifndef _RWSTD_NO_EXCEPTIONS
#ifdef _RW_STD_EXCEPT
#include <exception>
#endif
#endif // _RWSTD_NO_EXCEPTIONS



#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __save
#      pragma __environment __cxx_header_defaults
#   endif
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#pragma __extern_prefix __save
#pragma __extern_prefix "CXXL$" 
#endif


#if defined(__DECCXX) 
// disable this workaround, at least for now, since it
// doesn't compile in cfront or gnu mode, and we
// can't cause link incompatibilities between the -std modes 
#define __DECFIXCXXL1231 
#endif

#if defined(__DECCXX) && !defined(__DECFIXCXXL1231)

// define bitmask type according to section 17.3.2.1.2 of the standard

enum _Bitmask { V0 = 1 << 0, V1 = 1 << 1, V2 = 1 << 2, V3 = 1 << 3, V4 = 1 << 4, V5 = 1 << 5 };

inline _Bitmask operator& (_Bitmask X, _Bitmask Y)
{
	return static_cast<_Bitmask>(static_cast<int>(X) & static_cast<int>(Y));
}

inline _Bitmask operator| (_Bitmask X, _Bitmask Y)
{
	return static_cast<_Bitmask>(static_cast<int>(X) | static_cast<int>(Y));
}

inline _Bitmask operator^ (_Bitmask X, _Bitmask Y)
{
	return static_cast<_Bitmask>(static_cast<int>(X) ^ static_cast<int>(Y));
}

inline _Bitmask operator~ (_Bitmask X)
{
	return static_cast<_Bitmask>(~ static_cast<int>(X));
}

inline _Bitmask& operator&= (_Bitmask& X, _Bitmask Y)
{
	X = X & Y; return X;
}

inline _Bitmask& operator|= (_Bitmask& X, _Bitmask Y)
{
	X = X | Y; return X;
}

inline _Bitmask& operator^= (_Bitmask& X, _Bitmask Y)
{
	X = X ^ Y; return X;
}

#endif

#ifndef _RWSTD_NO_NAMESPACE
namespace std {
#endif

  typedef long         SZ_T;       
  typedef SZ_T         streamsize;

  class __Wide_Init 
  {
#if defined(__DECCXX) && !defined(__DECFIXCXXL957)
    static int    _RWinitcnt;
#else
    static int    _RWinit_cnt;
#endif
  public:
#if defined(__DECCXX) && !defined(__DECFIXCXXL957)
    static int    getinit_cnt_() { return _RWinitcnt;}
#else
    static int    getinit_cnt_() { return _RWinit_cnt;}
#endif
    __Wide_Init();
    ~__Wide_Init();
  };

  /*
   *     Class ios_base
   */

  class _RWSTDExport ios_base
  {
  public:

#ifndef _RWSTD_NO_EXCEPTIONS
#ifdef  _RW_STD_EXCEPT
    class _RWSTDExport failure : public exception
    {
    public:
      _EXPLICIT failure(const string& msg);
      virtual ~failure() _RWSTD_THROW_SPEC_NULL;
      virtual const char* what() const _RWSTD_THROW_SPEC_NULL;

    private:
      string _RWstr;
    };
#endif // _RW_STD_EXCEPT
#endif // _RWSTD_NO_EXCEPTIONS
    typedef int      fmtflags;
    
#if defined(__DECCXX) && !defined(__DECFIXCXXL1035)
      static const fmtflags boolalpha   = 0x0001;
      static const fmtflags dec         = 0x0002;
      static const fmtflags fixed       = 0x0004;
      static const fmtflags hex         = 0x0008;
      static const fmtflags internal    = 0x0010;
      static const fmtflags left        = 0x0020;
      static const fmtflags oct         = 0x0040;
      static const fmtflags right       = 0x0080;
      static const fmtflags scientific  = 0x0100;
      static const fmtflags showbase    = 0x0200;
      static const fmtflags showpoint   = 0x0400; 
      static const fmtflags showpos     = 0x0800; 
      static const fmtflags skipws      = 0x1000; 
      static const fmtflags unitbuf     = 0x2000; 
      static const fmtflags uppercase   = 0x4000; 
      static const fmtflags adjustfield = left | right | internal;
      static const fmtflags basefield   = dec | oct | hex;
      static const fmtflags floatfield  = scientific | fixed;
#else
    enum fmt_flags {
      boolalpha   = 0x0001,
      dec         = 0x0002,
      fixed       = 0x0004,
      hex         = 0x0008,
      internal    = 0x0010,
      left        = 0x0020,
      oct         = 0x0040,
      right       = 0x0080,
      scientific  = 0x0100,
      showbase    = 0x0200, 
      showpoint   = 0x0400, 
      showpos     = 0x0800, 
      skipws      = 0x1000, 
      unitbuf     = 0x2000, 
      uppercase   = 0x4000, 
      adjustfield = left | right | internal,
      basefield   = dec | oct | hex,
      floatfield  = scientific | fixed
    };
#endif
    
    typedef int      iostate;


#if defined(__DECCXX) && !defined(__DECFIXCXXL1035)
      static const iostate goodbit = 0x00;   
      static const iostate badbit = 0x01;   
      static const iostate eofbit = 0x02;  
      static const iostate failbit = 0x04;  
#else
    enum io_state {
      goodbit     = 0x00,   
      badbit      = 0x01,   
      eofbit      = 0x02,  
      failbit     = 0x04  
    };
#endif

#if defined(__DECCXX) && !defined(__DECFIXCXXL1231)
    typedef _Bitmask openmode;
#else
    typedef int      openmode;
#endif

#if defined(__DECCXX) && !defined(__DECFIXCXXL1231)
      static const openmode app = V0;   
      static const openmode binary = V1;  
      static const openmode in = V2; 
      static const openmode out = V3;   
      static const openmode trunc = V4;                 
      static const openmode ate = V5; 
#else
    enum open_mode {
      app         = 0x01,   
      binary      = 0x02,  
      in          = 0x04, 
      out         = 0x08,   
      trunc       = 0x10,                  
      ate         = 0x20 
    };
#endif

    typedef int      seekdir;

#if defined(__DECCXX) && !defined(__DECFIXCXXL1035)
    static const seekdir beg = 0x0;    
    static const seekdir cur = 0x1;    
    static const seekdir end = 0x2;   
#else
    enum seek_dir {
      beg         = 0x0,    
      cur         = 0x1,    
      end         = 0x2   
    };        
#endif

    class Init {
#if defined(__DECCXX) && !defined(__DECFIXCXXL957)
      static int    _RWinitcnt;
#else
      static int    _RWinit_cnt;
#endif
    public:
#if defined(__DECCXX) && !defined(__DECFIXCXXL957)
      static int    getinit_cnt_() { return _RWinitcnt;}
#else
      static int    getinit_cnt_() { return _RWinit_cnt;}
#endif
      Init();
      ~Init();
    };

    inline fmtflags flags() const;
    inline fmtflags flags(fmtflags fmtfl);
    inline fmtflags setf(fmtflags fmtfl);
    inline fmtflags setf(fmtflags fmtfl, fmtflags mask);
    inline void unsetf(fmtflags mask);

    inline streamsize precision() const;
    inline streamsize precision(streamsize prec);
    inline streamsize width() const;
    inline streamsize width(streamsize wide);

    locale imbue(const locale& loc);
    locale getloc() const
    { return _RWloc; }

    static int xalloc();
    long&  iword(int index);
    void*& pword(int index);

    enum event { 
      erase_event   = 0x0001,
      imbue_event   = 0x0002,
      copyfmt_event = 0x0004
    };

    typedef void (*event_callback) (event, ios_base&, int index);
    void register_callback( event_callback fn, int index);
    
    ios_base& copyfmt(const ios_base& rhs);
    ios_base& _RW_UNSAFE_copyfmt(const ios_base& rhs);

    bool is_synch() 
    { return _RWsync_with_stdio; }


#if defined(__DECCXX) && !defined(__DECFIXCXXL1037)
    static inline bool sync_with_stdio(bool sync = true)
#else
    bool sync_with_stdio(bool sync = true)
#endif
    { 
      bool tmp =_RWsync_with_stdio;
      _RWsync_with_stdio = sync;
      return tmp;
    }

  protected:

    ios_base();

#if defined(__DECCXX) && !defined(__DECFIXCXXL1036)
  public:
#endif
    virtual ~ios_base();    
#if defined(__DECCXX) && !defined(__DECFIXCXXL1036)
  protected:
#endif


    fmtflags           _RWfmtfl; 
    streamsize         _RWprec;   
    streamsize         _RWwide;   
    
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDMutex _RWstream_mutex;
#endif

  private:

    void usersize(int);
    locale             _RWloc;

    union ios_user_union {
      long         _RWlword;
      void        *_RWpword;
    };

    struct register_call {
      int             _RWindex;
      event_callback  _RWfn;
    }; 

    static int                  _RWindex;
    int                         _RWindex_cp;
    int                         _RWindex_callback;  
    union  ios_user_union      *_RWuserwords; 
    struct register_call       *_RWregistered_call;
    static bool                 _RWsync_with_stdio;
  };
 
  /*
   *     inline definitions
   */
 
  /*
   * fmtflags flags() const
   */

  inline ios_base::fmtflags 
  ios_base::flags() const
  {
    return _RWfmtfl;
  }

  /*
   * fmtflags flags(fmtflags)
   */

  inline ios_base::fmtflags 
  ios_base::flags(ios_base::fmtflags flgs)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif
    ios_base::fmtflags      f = _RWfmtfl;
    _RWfmtfl = flgs;
    return f;
  }

  /*
   * fmtflags setf(fmtflags)
   */

  inline ios_base::fmtflags 
  ios_base::setf(ios_base::fmtflags flgs)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif
    ios_base::fmtflags       f = _RWfmtfl;
    _RWfmtfl |= flgs;
    return f;
  }

  /*
   * fmtflags setf(fmtflags, fmtflags)
   */

  inline ios_base::fmtflags 
  ios_base::setf(ios_base::fmtflags flgs, ios_base::fmtflags mask)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif
    ios_base::fmtflags      old = _RWfmtfl;
    _RWfmtfl &= ~mask;
    _RWfmtfl |= (flgs & mask);
    return old;
  }

  /*
   * void unsetf(fmtflags)
   */

  inline void 
  ios_base::unsetf(ios_base::fmtflags fg)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif
    _RWfmtfl &= ~fg;
  }

  /*
   * streamsize precision() const
   */

  inline streamsize 
  ios_base::precision() const
  {
    return _RWprec;
  }

  /*
   * streamsize precision(streamsize)
   */


  inline streamsize 
  ios_base::precision(streamsize p)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif
    streamsize    temp = _RWprec;
    _RWprec = p;
    return temp;
  }

  /*
   * streamsize width() const
   */

  inline streamsize 
  ios_base::width() const
  {
    return _RWwide;
  }

  /*
   * streamsize width(streamsize)
   */

  inline streamsize 
  ios_base::width(streamsize w)
  {
#ifdef _RWSTD_MULTI_THREAD
    _RWSTDGuard guard(this->_RWstream_mutex);
#endif
    streamsize      i = _RWwide;
    _RWwide = w;
    return i;
  }

  /*
   *     External declarations for manipulators
   */

  inline ios_base& unitbuf(ios_base& strm)
  {
    strm.setf(ios_base::unitbuf);
    return strm;
  }

  /*
   * unset the unitbuf mode
   */

  inline ios_base& nounitbuf(ios_base& strm)
  {
    strm.unsetf(ios_base::unitbuf);
    return strm;
  }

  /*
   * says that bool will be inserted/extracted as
   * false/true depending on locale
   */

  inline ios_base& boolalpha(ios_base& strm)
  {
    strm.setf(ios_base::boolalpha);
    return strm;
  }

  /*
   * bool is inserted/extraced as 0/1
   v   */

  inline ios_base& noboolalpha(ios_base& strm)
  {
    strm.unsetf(ios_base::boolalpha);
    return strm;
  }

  /*
   * shows the base of the number e.g. 0777 for oct, 0x for hex
   */

  inline ios_base& showbase(ios_base& strm)
  {
    strm.setf(ios_base::showbase);
    return strm;
  }

  /*
   * does not show the base
   */

  inline ios_base& noshowbase(ios_base& strm)
  {
    strm.unsetf(ios_base::showbase);
    return strm;
  }

  /*
   * shows the decimal point on floating insertion even if not necessary
   */

  inline ios_base& showpoint(ios_base& strm)
  { 
    strm.setf(ios_base::showpoint);
    return strm;
  }

  /*
   * does not show the decimal point if not necessary
   */

  inline ios_base& noshowpoint(ios_base& strm)
  {
    strm.unsetf(ios_base::showpoint);
    return strm;
  }

  /*
   * prints the sign of the number.  will also print '+' for positive #'s
   */

  inline ios_base& showpos(ios_base& strm)
  {
    strm.setf(ios_base::showpos);
    return strm;
  }

  /*
   * only shows the sign for negative values
   */

  inline ios_base& noshowpos(ios_base& strm)
  {
    strm.unsetf(ios_base::showpos);
    return strm;
  }

  /*
   * skips the white space when reading characters
   */

  inline ios_base& skipws(ios_base& strm)
  {
    strm.setf(ios_base::skipws);
    return strm;
  }

  /*
   * doesn't skip white space when reading characters
   */

  inline ios_base& noskipws(ios_base& strm)
  {
    strm.unsetf(ios_base::skipws);
    return strm;
  }

  /*
   * prints floating point and hex values in uppercase.
   * e.g. 1.234E05, 0X1B
   */

  inline ios_base& uppercase(ios_base& strm)
  {
    strm.setf(ios_base::uppercase);
    return strm;
  }

  /*
   * uses lowercase for floating point and hex values
   */

  inline ios_base& nouppercase(ios_base& strm)
  {
    strm.unsetf(ios_base::uppercase);
    return strm;
  }

  inline ios_base& internal(ios_base& strm)
  {
    strm.setf(ios_base::internal, ios_base::adjustfield);
    return strm;
  }

  /*
   * does left justifying
   */

  inline ios_base& left(ios_base& strm)
  {
    strm.setf(ios_base::left, ios_base::adjustfield);
    return strm;
  }

  /*
   * does right justifying
   */

  inline ios_base& right(ios_base& strm)
  {
    strm.setf(ios_base::right, ios_base::adjustfield);
    return strm;
  }

  /*
   * prints integer values in decimal
   */

  inline ios_base& dec(ios_base& strm)
  {
    strm.setf(ios_base::dec, ios_base::basefield);
    return strm;
  }

  /*
   * prints integer values in hexadecimal
   */

  inline ios_base& hex(ios_base& strm)
  {
    strm.setf(ios_base::hex, ios_base::basefield);
    return strm;
  }

  /*
   * prints integer values in octal
   */

  inline ios_base& oct(ios_base& strm)
  {
    strm.setf(ios_base::oct, ios_base::basefield);
    return strm;
  }

  /*
   * generate floating point numbers in fixed-point notation
   */

  inline ios_base& fixed(ios_base& strm)
  {
    strm.setf(ios_base::fixed, ios_base::floatfield);
    return strm;
  }

  /*
   * generates floating-point numbers in scientific notation
   */

  inline ios_base& scientific(ios_base& strm)
  {
    strm.setf(ios_base::scientific, ios_base::floatfield);
    return strm;
  }

  // end inlining

#ifndef _RWSTD_NO_NAMESPACE
}
#endif

#if defined(__VMS) && defined(__DECCXX) && !defined(__DECFIXCXXL1158)
#   pragma __extern_prefix __restore
#endif

#if defined(__DECCXX)
#   ifdef __PRAGMA_ENVIRONMENT
#      pragma __environment __restore
#   endif
#endif

#endif // __USE_STD_IOSTREAM

#endif // __STD_IOSBASE__ 
