/*
 * Copyright (C) 1997-2003 by Objective Systems, Inc.
 *
 * This software is furnished under a license and may be used and copied
 * only in accordance with the terms of such license and with the
 * inclusion of the above copyright notice. This software or any other
 * copies thereof may not be provided or otherwise made available to any
 * other person. No title to and ownership of the software is hereby
 * transferred.
 *
 * The information in this software is subject to change without notice
 * and should not be construed as a commitment by Objective Systems, Inc.
 *
 * PROPRIETARY NOTICE
 *
 * This software is an unpublished work subject to a confidentiality agreement
 * and is protected by copyright and trade secret law.  Unauthorized copying,
 * redistribution or other use of this work is prohibited.
 *
 * The above notice of copyright on this source code product does not indicate
 * any actual or intended publication of such source code.
 *
 *****************************************************************************/

/** 
 * @file OSCStream.h 
 * C++ base class definitions for operations with I/O streams.
 */

#ifndef _OSCSTREAM_H_
#define _OSCSTREAM_H_

#include "asn1CppTypes.h"
#include "rtStream.h"

/** @defgroup streamclass C++ definitions for streams.
 * @ingroup cppruntime 
 * @{
 */

/** @defgroup strmencwrappers Wrapper classes for encoding using operator <<
 * These classes can be used for encoding data using the << operator.
 * For example: CustomOutputStream os; ..... os << OSEncStrmInt (2) <<
 * OSEncStrmUInt8 (3) << OSEncStrmNull (); @{
 */

/**
 * A wrapper class for encoding a 32-bit integer value.
 */
struct EXTERNRT OSEncStrmInt {
   ASN1INT value; ///< a value

   /** A constructor */
   OSEncStrmInt (ASN1INT val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmInt (const OSEncStrmInt& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding an 8-bit integer value.
 */
struct EXTERNRT OSEncStrmInt8 {
   ASN1INT8 value; ///< a value

   /** A constructor */
   OSEncStrmInt8 (ASN1INT8 val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmInt8 (const OSEncStrmInt8& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding a 16-bit integer value.
 */
struct EXTERNRT OSEncStrmInt16 {
   ASN1SINT value; ///< a value

   /** A constructor */
   OSEncStrmInt16 (ASN1SINT val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmInt16 (const OSEncStrmInt16& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding a 64-bit integer value.
 */
struct EXTERNRT OSEncStrmInt64 {
   ASN1INT64 value; ///< a value

   /** A constructor */
   OSEncStrmInt64 (ASN1INT64 val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmInt64 (const OSEncStrmInt64& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding a 32-bit unsigned integer value.
 */
struct EXTERNRT OSEncStrmUInt {
   ASN1UINT value; ///< a value

   /** A constructor */
   OSEncStrmUInt (ASN1UINT val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmUInt (const OSEncStrmUInt& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding an 8-bit unsigned integer value.
 */
struct EXTERNRT OSEncStrmUInt8 {
   ASN1UINT8 value; ///< a value

   /** A constructor */
   OSEncStrmUInt8 (ASN1UINT8 val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmUInt8 (const OSEncStrmUInt8& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding a 16-bit unsigned integer value.
 */
struct EXTERNRT OSEncStrmUInt16 {
   ASN1USINT value; ///< a value

   /** A constructor */
   OSEncStrmUInt16 (ASN1USINT val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmUInt16 (const OSEncStrmUInt16& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding a 64-bit unsigned integer value.
 */
struct EXTERNRT OSEncStrmUInt64 {
   ASN1UINT64 value; ///< a value

   /** A constructor */
   OSEncStrmUInt64 (ASN1UINT64 val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmUInt64 (const OSEncStrmUInt64& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding an enumerated value.
 */
struct EXTERNRT OSEncStrmEnum {
   ASN1ENUM value; ///< a value

   /** A constructor */
   OSEncStrmEnum (ASN1ENUM val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmEnum (const OSEncStrmEnum& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding a big integer value.
 */
struct EXTERNRT OSEncStrmBigInt {
   const char *pvalue; ///< a pointer to value

   /** A constructor */
   OSEncStrmBigInt (const char* pval) {
      pvalue = pval;
   }
   /** A constructor */
   OSEncStrmBigInt (const OSEncStrmBigInt& val) {
      pvalue = val.pvalue;
   }
} ;

/**
 * A wrapper class for encoding a real value.
 */
struct EXTERNRT OSEncStrmReal {
   ASN1REAL value; ///< a value

   /** A constructor */
   OSEncStrmReal (ASN1REAL val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmReal (const OSEncStrmReal& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding a bit string value.
 */
struct EXTERNRT OSEncStrmBitStr {
   ASN1UINT numbits;       ///< number of bits
   const ASN1OCTET* data;  ///< pointer to data

   /** A constructor */
   OSEncStrmBitStr (ASN1UINT _numbits, const ASN1OCTET* _data) :
      numbits (_numbits), data (_data) { }

   /** A constructor */
   OSEncStrmBitStr (const ASN1DynBitStr& _bs) :
      numbits (_bs.numbits), data (_bs.data) { }
} ;

/**
 * A wrapper class for encoding an octet string value.
 */
struct EXTERNRT OSEncStrmOctStr {
   ASN1UINT numocts;       ///< number of octets
   const ASN1OCTET* data;  ///< pointer to data

   /** A constructor */
   OSEncStrmOctStr (ASN1UINT _numocts, const ASN1OCTET* _data) :
      numocts (_numocts), data (_data) { }

   /** A constructor */
   OSEncStrmOctStr (const ASN1DynOctStr& _os) : 
      numocts (_os.numocts), data (_os.data) { }
} ;

/**
 * A wrapper class for encoding a BOOLEAN value.
 */
struct EXTERNRT OSEncStrmBool {
   ASN1BOOL value; ///< a value

   /** A constructor */
   OSEncStrmBool (ASN1BOOL val) {
      value = val;
   }
   /** A constructor */
   OSEncStrmBool (const OSEncStrmBool& val) {
      value = val.value;
   }
} ;

/**
 * A wrapper class for encoding a character string value.
 */
struct EXTERNRT OSEncStrmCharStr {
   const char* pvalue; ///< a pointer to value

   /** A constructor */
   OSEncStrmCharStr (const char* pval) {
      pvalue = pval;
   }
   /** A constructor */
   OSEncStrmCharStr (const OSEncStrmCharStr& val) {
      pvalue = val.pvalue;
   }
} ;

/**
 * A wrapper class for encoding an OBJECT IDENTIFIER value.
 */
struct EXTERNRT OSEncStrmObjId {
   const ASN1OBJID* pvalue; ///< a pointer to value

   /** A constructor */
   OSEncStrmObjId (const ASN1OBJID& oid) : pvalue (&oid) {}
   /** A constructor */
   OSEncStrmObjId (const ASN1TObjId& oid) : pvalue (&oid) {}
} ;

/**
 * A wrapper class for encoding a RELATIVE-OID value.
 */
struct EXTERNRT OSEncStrmRelativeOID : public OSEncStrmObjId {
   /** A constructor */
   OSEncStrmRelativeOID (const ASN1OBJID& oid) : OSEncStrmObjId (oid) {}
   /** A constructor */
   OSEncStrmRelativeOID (const OSEncStrmObjId& oid) : OSEncStrmObjId (oid) {}
} ;

/**
 * A wrapper class for encoding a NULL value.
 */
struct EXTERNRT OSEncStrmNull {};

/**
 * A wrapper class for encoding a BMP string value.
 */
struct EXTERNRT OSEncStrmBMPString {
   const Asn116BitCharString* pvalue;

   /** A constructor */
   OSEncStrmBMPString (const Asn116BitCharString& val) {
      pvalue = &val;
   }
} ;

/**
 * A wrapper class for encoding an universal string value.
 */
struct EXTERNRT OSEncStrmUnivString {
   const Asn132BitCharString* pvalue;

   /** A constructor */
   OSEncStrmUnivString (const Asn132BitCharString& val) {
      pvalue = &val;
   }
} ;

/** @} */

/** @defgroup strmdecwrappers Wrapper classes for decoding using operator >>
 * These wrapper classes can be used for decoding data using the >> operator.
 * For example: CustomInputStream is; ..... is >> OSDecStrmInt (v1) >>
 * OSDecStrmUInt8 (v2) >> OSDecStrmNull (); @{
 */

/**
 * A wrapper class for decoding a 32-bit integer value.
 */
struct EXTERNRT OSDecStrmInt {
   ASN1INT& value; ///< a value

   /** A constructor */
   OSDecStrmInt (ASN1INT& val) : value (val) { }
   /** A constructor */
   OSDecStrmInt (OSDecStrmInt& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding an 8-bit integer value.
 */
struct EXTERNRT OSDecStrmInt8 {
   ASN1INT8& value; ///< a value

   /** A constructor */
   OSDecStrmInt8 (ASN1INT8& val) : value (val) { }
   /** A constructor */
   OSDecStrmInt8 (OSDecStrmInt8& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding a 16-bit integer value.
 */
struct EXTERNRT OSDecStrmInt16 {
   ASN1SINT& value; ///< a value

   /** A constructor */
   OSDecStrmInt16 (ASN1SINT& val) : value (val) { }
   /** A constructor */
   OSDecStrmInt16 (OSDecStrmInt16& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding a 64-bit integer value.
 */
struct EXTERNRT OSDecStrmInt64 {
   ASN1INT64& value; ///< a value

   /** A constructor */
   OSDecStrmInt64 (ASN1INT64& val) : value (val) { }
   /** A constructor */
   OSDecStrmInt64 (OSDecStrmInt64& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding a 32-bit unsigned integer value.
 */
struct EXTERNRT OSDecStrmUInt {
   ASN1UINT& value; ///< a value

   /** A constructor */
   OSDecStrmUInt (ASN1UINT& val) : value (val) { }
   /** A constructor */
   OSDecStrmUInt (OSDecStrmUInt& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding an 8-bit unsigned integer value.
 */
struct EXTERNRT OSDecStrmUInt8 {
   ASN1OCTET& value; ///< a value

   /** A constructor */
   OSDecStrmUInt8 (ASN1OCTET& val) : value (val) { }
   /** A constructor */
   OSDecStrmUInt8 (OSDecStrmUInt8& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding a 16-bit unsigned integer value.
 */
struct EXTERNRT OSDecStrmUInt16 {
   ASN1USINT& value; ///< a value

   /** A constructor */
   OSDecStrmUInt16 (ASN1USINT& val) : value (val) { }
   /** A constructor */
   OSDecStrmUInt16 (OSDecStrmUInt16& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding a 64-bit unsigned integer value.
 */
struct EXTERNRT OSDecStrmUInt64 {
   ASN1UINT64& value; ///< a value

   /** A constructor */
   OSDecStrmUInt64 (ASN1UINT64& val) : value (val) { }
   /** A constructor */
   OSDecStrmUInt64 (OSDecStrmUInt64& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding an enumerated value.
 */
struct EXTERNRT OSDecStrmEnum {
   ASN1ENUM& value; ///< a value

   /** A constructor */
   OSDecStrmEnum (ASN1ENUM& val) : value (val) { }
   /** A constructor */
   OSDecStrmEnum (OSDecStrmEnum& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding a big integer value.
 */
struct EXTERNRT OSDecStrmBigInt {
   const char*& pvalue; /// a pointer to value

   /** A constructor */
   OSDecStrmBigInt (const char*& pval) : pvalue (pval) { }
   /** A constructor */
   OSDecStrmBigInt (OSDecStrmBigInt& val) : pvalue (val.pvalue) { }
} ;

/**
 * A wrapper class for decoding a real value.
 */
struct EXTERNRT OSDecStrmReal {
   ASN1REAL& value; ///< a value

   /** A constructor */
   OSDecStrmReal (ASN1REAL& val) : value (val) { }
   /** A constructor */
   OSDecStrmReal (OSDecStrmReal& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding a size-fixed bit string value.
 */
struct EXTERNRT OSDecStrmBitStr {
   ASN1UINT& numbits; ///< number of bits
   ASN1OCTET*& data;  ///< pointer to data

   /** A constructor */
   OSDecStrmBitStr (ASN1UINT& _numbits, ASN1OCTET*& _data) :
      numbits (_numbits), data (_data) { }
} ;

/**
 * A wrapper class for decoding a dynamic bit string value.
 */
struct EXTERNRT OSDecStrmDynBitStr {
   ASN1DynBitStr& val; ///< a value

   /** A constructor */
   OSDecStrmDynBitStr (ASN1DynBitStr& _bs) : val (_bs) {}
} ;

/**
 * A wrapper class for decoding a size-fixed octet string value.
 */
struct EXTERNRT OSDecStrmOctStr {
   ASN1UINT& numocts; ///< number of octets
   ASN1OCTET*& data;  ///< pointer to data

   /** A constructor */
   OSDecStrmOctStr (ASN1UINT& _numocts, ASN1OCTET*& _data) :
      numocts (_numocts), data (_data) { }
} ;

/**
 * A wrapper class for decoding a dynamic octet string value.
 */
struct EXTERNRT OSDecStrmDynOctStr {
   ASN1DynOctStr& val; ///< a value

   /** A constructor */
   OSDecStrmDynOctStr (ASN1DynOctStr& _os) : val (_os) {}
} ;

/**
 * A wrapper class for decoding a BOOLEAN value.
 */
struct EXTERNRT OSDecStrmBool {
   ASN1BOOL& value; ///< a value

   /** A constructor */
   OSDecStrmBool (ASN1BOOL& val) : value (val) { }
   /** A constructor */
   OSDecStrmBool (OSDecStrmBool& val) : value (val.value) { }
} ;

/**
 * A wrapper class for decoding a character string value.
 */
struct EXTERNRT OSDecStrmCharStr {
   const char*& pvalue; ///< pointer to string data
   ASN1TAG tag;         ///< tag of the string

   /** A constructor */
   OSDecStrmCharStr (const char*& pval, ASN1TAG _tag) : 
      pvalue (pval), tag (_tag) {}
   /** A constructor */
   OSDecStrmCharStr (OSDecStrmCharStr& val) : 
      pvalue (val.pvalue), tag (val.tag) { }
} ;

/**
 * A wrapper class for decoding an OBJECT IDENTIFIER value.
 */
struct EXTERNRT OSDecStrmObjId {
   ASN1OBJID& value; ///< a value

   /** A constructor */
   OSDecStrmObjId (ASN1OBJID& oid) : value (oid) {}
   /** A constructor */
   OSDecStrmObjId (ASN1TObjId& oid) : value (oid) {}
} ;

/**
 * A wrapper class for decoding a RELATIVE-OID value.
 */
struct EXTERNRT OSDecStrmRelativeOID : public OSDecStrmObjId {
   /** A constructor */
   OSDecStrmRelativeOID (ASN1OBJID& oid) : OSDecStrmObjId (oid) {}
   /** A constructor */
   OSDecStrmRelativeOID (OSDecStrmObjId& oid) : OSDecStrmObjId (oid) {}
} ;

/**
 * A wrapper class for decoding a NULL value.
 */
struct EXTERNRT OSDecStrmNull {};

/**
 * A wrapper class for decoding a BMP string value.
 */
struct EXTERNRT OSDecStrmBMPString {
   Asn116BitCharString& value; ///< a value

   /** A constructor */
   OSDecStrmBMPString (Asn116BitCharString& val) : value (val) { }
} ;

/**
 * A wrapper class for decoding an universal string value.
 */
struct EXTERNRT OSDecStrmUnivString {
   Asn132BitCharString& value; ///< a value

   /** A constructor */
   OSDecStrmUnivString (Asn132BitCharString& val) : value (val) { }
} ;

/** @} */

/** @defgroup strmclasses C++ base classes for stream operations.
 * @{
 */

/** 
 * Exception class for streams.
 */
class EXTERNRT OSCStreamException : public ASN1RTLException {
 public:
   OSCStreamException (int stat) : ASN1RTLException(stat) {}
} ;

/**
 * The base class for streams.
 */
#if !defined NO_ASN1_RT_REDUNDANT
class EXTERNRT OSCStream {
 protected:
   ASN1CtxtPtr mpContext; ///< The pointer to context structure
   ASN1BOOL    buffered;  ///< The indicator that a buffered stream is used
 public:
   /**
    * The default constructor. It initializes a buffered stream.  A 
    * buffered stream maintains data in memory before reading or writing 
    * to the device.  This generally provides better performance than 
    * an unbuffered stream.
    *
    * @exception OSCStreamException    stream can't be created or initialized.
    */
   OSCStream ();

   /**
    * This constructor initializes either a buffered or unbuffered stream 
    * based on the '_buffered' boolean parameter.
    *
    * @param _buffered                 If TRUE, constructor will create and
    *                                    initialize a buffered stream; 
    *                                    otherwise, an unbuffered stream 
    *                                    will be used.
    * @exception OSCStreamException    stream can't be created or initialized.
    */
   OSCStream (ASN1BOOL _buffered);

   /**
    * A destructor. Closes the stream if it was opened.
    */
   virtual ~OSCStream ();

   /**
    * Closes the input or output stream and releases any system resources
    * associated with the stream. For output streams this function also flushes
    * all internal buffers to the stream.
    *
    * @see               ::rtStreamClose, ::rtStreamBufClose
    * @exception OSCStreamException    I/O error occurred.
    */
   virtual void close ();

   /**
    * Flushes the buffered data to the stream.
    *
    * @see               ::rtStreamFlush, ::rtStreamBufFlush
    * @exception OSCStreamException    I/O error occurred.
    */
   virtual void flush ();

   /**
    * Returns the pointer to context wrapper class.
    */
   inline ASN1CtxtPtr getContext () {
      return mpContext;
   }
   /**
    * Returns the pointer to context structure.
    */
   inline ASN1CTXT* getCtxtPtr () {
      return mpContext->GetPtr();
   }
} ;
#endif	/* !NO_ASN1_RT_REDUNDANT */
/** @} */

#endif /* _OSCSTREAM_H_ */

