/*
 * 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.
 *
 *****************************************************************************/
//
// CHANGE LOG
// Date         Init    Description
// 04/19/02     ED      Added XEREncode, XERDecode message buffer types
// 04/19/02     ED      Removed StringOverflow and added RTLError excp
// 07/14/02     ED      Changed all methods to being with lowercase 
//                      char for consistency.  Added deprecated inline 
//                      methods for those that did not to maintain 
//                      backward compatibility.
// 07/16/02     AB      added 'const' to RTLError::getStatus
// 10/29/02     CZ      Added/modified doxygen code for groups.
//
////////////////////////////////////////////////////////////////////////////

/** 
 * @file asn1CppTypes.h 
 * Common C++ type and class definitions.
 */
#ifndef _ASN1CPPTYPES_H_
#define _ASN1CPPTYPES_H_

#if !defined NO_ASN1_RT_REDUNDANT
#   define NO_ASN1_RT_REDUNDANT
#endif /* !NO_ASN1_RT_REDUNDANT */

#include "asn1CppEvtHndlr.h"

#ifndef _NO_EXCEPTIONS
#define ASN1TRY try
#define ASN1RTLTHROW(stat) throw ASN1MessageBuffer::RTLError(stat)
#define ASN1THROW(ex) throw ex
#define ASN1CATCH(exType,ex,body) catch (exType ex) { body; }
#else 
#define ASN1TRY
#define ASN1RTLTHROW(stat) do { \
fprintf (stderr, "Fatal Error in %s at %i, stat = %i\n", __FILE__, __LINE__, stat); \
exit (-1); \
} while(0)
#define ASN1THROW(ex) do { \
fprintf (stderr, "Fatal Error in %s at %i\n", __FILE__, __LINE__); \
exit (-1); \
} while (0)
#define ASN1CATCH(exType,ex,body)
#endif

/** 
 * @defgroup cppruntime C++ Run-Time Classes 
 * @{
 */
/**
 * @defgroup asn1context Context Management Classes 
 * This group of classes manages an ASN1CTXT structure. This is the C structure
 * use to keep track of all of the working variables required to encode or
 * decode an ASN.1 message. @{
 */
/** 
 * Reference counted ASN.1 context class. This keeps track of all encode/decode
 * function variables between function invocations. It is reference counted to
 * allow a message buffer and type class to share access to it.
 */
class EXTERNRT ASN1Context {
 protected:
   /**
    * The mCtxt member variable is a standard C runtime context variable used
    * in most C runtime function calls.
    */
   ASN1CTXT mCtxt;

   /**
    * The mCount member variable holds the reference count of this context.
    */
   unsigned mCount;

 public:
   /**
    * The default constructor initializes the mCtxt member variable and sets
    * the reference count variable (mCount) to zero.
    */
   ASN1Context ();

   /**
    * The destructor frees all memory held by the context.
    */
   ~ASN1Context ();

   /**
    * The GetPtr method returns a pointer to the mCtxt member variable. A user
    * can use this function to get the the context pointer variable for use in
    * a C runtime function call.
    */
   ASN1CTXT* GetPtr () {
      return &mCtxt;
   }

   /**
    * The PrintErrorInfo method prints information on errors contained within
    * the context.
    */
   void PrintErrorInfo ();

   /**
    * The _ref method increases the reference count by one.
    */
   void _ref();

   /**
    * The _unref method decreases the reference count by one.
    */
   void _unref();

   /**
    * The getRefCount method returns the current reference count.
    */
   unsigned getRefCount();
};

/** 
 * ASN.1 context reference counted pointer class. This class allows an ASN.1
 * context object to automatically be released when its reference count goes to
 * zero (note: this should be a template class but due to portability problems
 * with templates a standard class is used). It is very similar to the standard
 * C++ library auto_ptr smart pointer class but only works with an ASN1Context
 * object.
 */
class EXTERNRT ASN1CtxtPtr {
 protected:
   /**
    * The mPointer member variable is a pointer to a reference-counted ASN.1
    * context wrapper class object.
    */
   ASN1Context* mPointer;

 public:
   /**
    * This constructor set the internal context pointer to the given value and,
    * if it is non-zero, increases the reference count by one.
    *
    * @param rf           - Pointer to ASN1Context object
    */
   ASN1CtxtPtr (ASN1Context* rf = 0) : mPointer(rf) { 
      if (mPointer != 0) mPointer->_ref(); 
   }

   /**
    * The copy constructor copies the pointer from the source pointer object
    * and, if it is non-zero, increases the reference count by one.
    *
    * @param o            - Reference to ASN1CtxtPtr object to be copied
    */
   ASN1CtxtPtr (const ASN1CtxtPtr& o) : mPointer(o.mPointer) {
      if (mPointer != 0) mPointer->_ref();
   }

   /**
    * The destructor decrements the reference counter to the internal context
    * pointer object. The context object will delete itself if its reference
    * count goes to zero.
    */
   ~ASN1CtxtPtr() { if (mPointer != 0) mPointer->_unref(); }

   /**
    * This assignment operator assigns this ASN1CtxtPtr to another. The
    * reference count of the context object managed by this object is first
    * decremented. Then the new pointer is assigned and that object's reference
    * count is incremented.
    *
    * @param rf           - Pointer to ASN1CtxtPtr smart-pointer object
    */
   ASN1CtxtPtr& operator= (const ASN1CtxtPtr& rf) {
      if (mPointer != 0) mPointer->_unref(); 
      mPointer = rf.mPointer;
      if (mPointer != 0) mPointer->_ref();
      return *this;
   }

   /**
    * This assignment operator assigns does a direct assignment of an
    * ASN1Context object to this ASN1CtxtPtr object.
    */
   ASN1CtxtPtr& operator= (ASN1Context* rf) {
      if (mPointer != 0) mPointer->_unref(); 
      mPointer = rf;
      if (mPointer != 0) mPointer->_ref();
      return *this;
   }

   /**
    * The 'ASN1Context*' operator returns the context object pointer.
    */
   operator ASN1Context* () { return mPointer; }
   operator const ASN1Context* () const { return mPointer; }

   /**
    * The '->' operator returns the context object pointer.
    */
   ASN1Context* operator -> () { return mPointer; }
   const ASN1Context* operator -> () const { return mPointer; }

   /**
    * The '==' operator compares two ASN1Context pointer values.
    */
   int operator == (const ASN1Context* o) const { 
      return mPointer == o ? 1 : 0; 
   }

   /**
    * The isNull method returns TRUE if the underlying context pointer is NULL.
    */
   int isNull() const { return mPointer == 0 ? 1 : 0; }

   /**
    * The data method returns the context object pointer.
    */
   ASN1Context* data() { return mPointer; }
   const ASN1Context* data() const { return mPointer; }

};
/** @} */

/** 
 * @defgroup asn1excp Exception Classes 
 * These classes define exceptions that can be thrown from the C++ runtime
 * classes. @{
 */
/** 
 * The base exception class for run-time.
 */
class EXTERNRT ASN1RTLException {
 protected:
   /**
    * The mStatus member variable holds the status value which caused the
    * exception to be thrown.
    */
   int mStatus;

 public:
   /**
    * The constructor sets the status member variable value.
    *
    * @param stat         - The status value that caused the exceptiuon to be
    *                       thrown.
    */
   DLLNOINLINERT ASN1RTLException (int stat) : mStatus(stat) {}

   /**
    * The virtual destructor does nothing. It is overridden by derived versions
    * of this class.
    */
   DLLNOINLINERT virtual ~ASN1RTLException () {}

   /**
    * The getStatus method returns the runtime status code value.
    */
   int getStatus () const { return (mStatus); }

   DLLNOINLINERT ASN1RTLException( const ASN1RTLException& src )
       : mStatus(src.mStatus) {}
} ;
/** @} */

/** 
 * @defgroup asn1msgbuf Message Buffer Classes 
 * These classes are used to manage message buffers. During encoding, messages
 * are constructed within these buffers. During decoding, the messages to be
 * decoded are held in these buffers. @{
 */
/** 
 * Abstract message buffer or stream interface class. This is the base class
 * for both the in-memory message buffer classes and the run-time stream
 * classes.
 */
class EXTERNRT ASN1MessageBufferIF {
 public:
   enum Type { 
      BEREncode, BERDecode, PEREncode, PERDecode, XEREncode, XERDecode,
      XMLEncode, XMLDecode
#if !defined NO_ASN1_RT_REDUNDANT
, Stream
#endif	/* !NO_ASN1_RT_REDUNDANT */
   } ;

 protected:
   /**
    * The virtual destructor does nothing. It is overridden by derived versions
    * of this class.
    */
   virtual ~ASN1MessageBufferIF () {}

 public:
   // Virtual methods
   virtual ASN1CtxtPtr getContext () = 0;
   virtual ASN1CTXT* getCtxtPtr () = 0;
   virtual ASN1OCTET* getMsgCopy () { return 0; }
   virtual const ASN1OCTET* getMsgPtr () { return 0; }
   virtual void init () {}
   virtual int initBuffer (ASN1MemBuf& membuf) { (void)membuf; return ASN_E_NOTSUPP; }
   virtual int initBuffer (ASN116BITCHAR* unistr) { (void)unistr; return ASN_E_NOTSUPP; }
   virtual int initBuffer (char* str) { (void)str; return ASN_E_NOTSUPP; }
   virtual ASN1BOOL isA (Type bufferType) = 0;

   /**
    * The addEventHandler method is used to register a used-defined named event
    * handler. Methods from within this handler will be invoked when this
    * message buffer is used in the decoding of a message.
    *
    * @param pEventHandler    - Pointer to named event handler object to
    *                           register.
    */
#if !defined NO_ASN1_RT_REDUNDANT
   inline void addEventHandler (Asn1NamedEventHandler* pEventHandler) {
      Asn1NamedEventHandler::addEventHandler 
         (getCtxtPtr(), pEventHandler);
   }
#endif	/* !NO_ASN1_RT_REDUNDANT */

   /**
    * The removeEventHandler method is used to de-register a used-defined named
    * event handler.
    *
    * @param pEventHandler    - Pointer to named event handler object to
    *                           de-register.
    */
#if !defined NO_ASN1_RT_REDUNDANT
   inline void removeEventHandler (Asn1NamedEventHandler* pEventHandler) {
      Asn1NamedEventHandler::removeEventHandler 
         (getCtxtPtr(), pEventHandler);
   }
#endif	/* !NO_ASN1_RT_REDUNDANT */

   /**
    * The CStringToBMPString method is a utility function for converting a
    * null-terminated Ascii string into a BMP string. A BMP string contains
    * 16-bit Unicode characters.
    *
    * @param cstring      - Null-terminated character string to convert
    * @param pBMPString   - Pointer to BMP string target variable
    * @param pCharSet     - Pointer to permitted alphabet character set. If
    *                       provided, index to character within this set is
    *                       returned.
    */
#if !defined NO_ASN1_RT_REDUNDANT
   inline ASN1BMPString* CStringToBMPString (ASN1ConstCharPtr cstring, 
                                             ASN1BMPString* pBMPString, 
                                             Asn116BitCharSet* pCharSet = 0) {
      return rtCToBMPString (getCtxtPtr (), cstring, 
                             pBMPString, pCharSet);
   }
#endif	/* !NO_ASN1_RT_REDUNDANT */

   /**
    * The getByteIndex method is used to fetch the current byte offset within
    * the current working buffer. For encoding, this is the next location that
    * will be written to. For decoding, this is the next byte the parser will
    * read.
    */
   inline ASN1UINT getByteIndex () {
      return getCtxtPtr ()->buffer.byteIndex;
   }

   /**
    * The PrintErrorInfo method prints information on errors contained within
    * the context.
    */
   inline void printErrorInfo () {
      getContext ()->PrintErrorInfo ();
   }

   /**
    * The setErrorHandler method is used to register a used-defined error
    * handler. Methods from within this handler will be invoked when an error
    * occurs in decoding a message using this message buffer object.
    *
    * @param pErrorHandler    - Pointer to error handler object to register.
    */
#if !defined NO_ASN1_RT_REDUNDANT
   inline void setErrorHandler (Asn1ErrorHandler* pErrorHandler) {
      Asn1ErrorHandler::setErrorHandler 
         (getCtxtPtr(), pErrorHandler);
   }
#endif	/* !NO_ASN1_RT_REDUNDANT */
};

/** 
 * Abstract ASN.1 message buffer base class. This class is used to manage a
 * message buffer containing an ASN.1 message. For encoding, this is the buffer
 * the message is being built in. For decoding, it is a message that was read
 * into memory to be decoded. Further classes are derived from this to handle
 * encoding and decoding of messages for different encoding rules types.
 */
class EXTERNRT ASN1MessageBuffer : public ASN1MessageBufferIF {
 protected:
   /**
    * The mpContext member variable holds a reference-counted C runtime
    * variable. This context is used in calls to all C run-time functions.
    */
   ASN1CtxtPtr mpContext;

   /**
    * The Type member variable holds information on the derived message buffer
    * class type (for example, BEREncode).
    */
   Type mBufferType;

   /**
    * The protected constructor creates a new context and sets the buffer class
    * type.
    *
    * @param bufferType   Type of message buffer that is being created (for
    *                       example, BEREncode).
    */
   ASN1MessageBuffer (Type bufferType);

 public:
   /**
    * The virtual destructor does nothing. It is overridden by derived versions
    * of this class.
    */
   virtual ~ASN1MessageBuffer () {}

   /**
    * The getContext method returns the underlying context smart-pointer
    * object.
    */
   inline ASN1CtxtPtr getContext () {
      return mpContext;
   }

   /**
    * The getCtxtPtr method returns the underlying C runtime context. This
    * context can be used in calls to C runtime functions.
    */
   inline ASN1CTXT* getCtxtPtr () {
      return mpContext->GetPtr();
   }

   /**
    * The getMsgCopy method will return a copy of the encoded ASN.1 message
    * managed by the object.
    */
   virtual ASN1OCTET* getMsgCopy () {
      return 0;
   }

   /**
    * The getMsgPtr method will return a const pointer to the encoded ASN.1
    * message managed by the object.
    */
   virtual const ASN1OCTET* getMsgPtr () {
      return getCtxtPtr()->buffer.data;
   }

   /**
    * This version of the overloaded initBuffer method initializes the message
    * buffer to point at the memory contained within the referenced ASN1MemBuf
    * object.
    *
    * @param membuf       - ASN1MemBuf memory buffer class object reference.
    */
   virtual int initBuffer (ASN1MemBuf& membuf);

   /**
    * This version of the overloaded initBuffer method initializes the message
    * buffer to point at the given Unicode string. This is used mainly for XER
    * (XML) message decoding.
    *
    * @param unistr       - Pointer to a Unicode character string.
    */
   virtual int initBuffer (ASN116BITCHAR* unistr);

   /**
    * This version of the overloaded initBuffer method initializes the message
    * buffer to point at the given null-terminated character string.
    *
    * @param str          - Pointer to a null-terminated ASCII character
    *                       string.
    */
   virtual int initBuffer (char* str) { (void)str; return ASN_E_NOTSUPP; }

   // deprecated methods: all have been changed to begin with lowercase 
   // character (ED, 7/14/02)..
   inline ASN1OCTET* GetMsgCopy () { return getMsgCopy(); }
   inline const ASN1OCTET* GetMsgPtr () { return getMsgPtr(); }
   inline void Init () { init(); }
   inline void PrintErrorInfo () { printErrorInfo(); }

   /**
    * Message buffer internal exception class. This exception is thrown from
    * the constructor if the message buffer object cannot be created.
    */
   class EXTERNRT RTLError : public ASN1RTLException {
   public:
      /**
       * The constructor sets the internal status variable to the given value.
       *
       * @param stat         - Runtime error status code.
       */
      RTLError (int stat) : ASN1RTLException(stat) {}
   } ;

} ;
/** @} */

/**
 * @defgroup asn1ctrl Control (ASN1C_) Base Classes 
 * The ASN1C Control Base Classes are used as the base for compiler-generated
 * ASN1C_ classes. These are wrapper classes that can be used to encode/decode
 * PDU types and as helper classes for performing operations on complex data
 * types. @{
 */
/** 
 * ASN1C control class base class. This is the main base class for all
 * generated ASN1C_\<name\> control classes. It holds a variable of a generated
 * data type as well as the associated message buffer or stream class to which
 * a message will be encoded or from which a message will be decoded.
 */
class EXTERNRT ASN1CType {
 protected:
   /**
    * The mpContext member variable holds a reference-counted C runtime
    * variable. This context is used in calls to all C run-time functions. The
    * context pointed at by this smart-pointer object is shared with the
    * message buffer object contained within this class.
    */
   ASN1CtxtPtr mpContext;

   /**
    * The mpMsgBuf member variable is a pointer to a derived message buffer or
    * stream class that will manage the ASN.1 message being encoded or decoded.
    */
   ASN1MessageBufferIF* mpMsgBuf;

   /**
    * The default constructor sets the message pointer member variable to NULL
    * and creates a new context object.
    */
   DLLNOINLINERT ASN1CType () : mpContext (new ASN1Context()), mpMsgBuf (0) {}

   /**
    * This constructor sets the message pointer member variable to NULL and
    * initializes the context object to point at the given context value.
    *
    * @param ctxt         - Reference to a context object.
    */
   DLLNOINLINERT ASN1CType (ASN1Context& ctxt) : mpContext (&ctxt), mpMsgBuf (0) {}

   /**
    * The setMsgBuf method is used to set the internal message buffer pointer
    * to point at the given message buffer or stream object.
    *
    * @param msgBuf       - Reference to a message buffer or stream object.
    */
   void setMsgBuf (ASN1MessageBufferIF& msgBuf);

 public:
   /**
    * This constructor sets the internal message buffer pointer to point at the
    * given message buffer or stream object. The context is set to point at the
    * context contained within the message buffer object. Thus, the message
    * buffer and control class object share the context. It will not be
    * released until both objects are destroyed.
    *
    * @param msgBuf       - Reference to a message buffer or stream object.
    */
   DLLNOINLINERT ASN1CType (ASN1MessageBufferIF& msgBuf) : mpMsgBuf(&msgBuf) {
      mpContext = msgBuf.getContext();
   }

   /**
    * The copy constructor sets the internal message buffer pointer and context
    * to point at the message buffer and context from the original ASN1CType
    * object.
    *
    * @param orig         - Reference to a message buffer or stream object.
    */
   DLLNOINLINERT ASN1CType (const ASN1CType& orig) : mpContext (orig.mpContext), 
      mpMsgBuf (orig.mpMsgBuf) { }

   /**
    * The virtual destructor does nothing. It is overridden by derived versions
    * of this class.
    */
   DLLNOINLINERT virtual ~ASN1CType () {}

   /**
    * The getCtxtPtr method returns the underlying C runtime context. This
    * context can be used in calls to C runtime functions.
    */
   inline ASN1CTXT* getCtxtPtr () {
      return (!mpContext.isNull ()) ? mpContext->GetPtr() : 0;
   }

   /**
    * The memAlloc method allocates memory using the C runtime memory
    * management functions. The memory is tracked in the underlying context
    * structure. When both this ASN1CType derived control class object and the
    * message buffer object are destroyed, this memory will be freed.
    *
    * @param numocts      - Number of bytes of memory to allocate
    */
   inline void* memAlloc (int numocts) {
      return ASN1MALLOC (getCtxtPtr(), numocts);
   }

   /**
    * The \c memFreeAll method will free all memory currently tracked within
    * the context. This includes all memory allocated with the memAlloc method
    * as well as any memory allocated using the C \c rtMemAlloc function with
    * the context returned by the \c getCtxtPtr method.
    */
   /* inline void memFreeAll () { */
   /*    ASN1MEMFREE (getCtxtPtr ()); */
   /* } */

   /**
    * The memRealloc method reallocates memory using the C runtime memory
    * management functions.
    *
    * @param ptr          - Original pointer containing dynamic memory to be
    *                       resized.
    * @param numocts      - Number of bytes of memory to allocate
    * @return             Reallocated memory pointer
    */
   inline void* memRealloc (void* ptr, int numocts) {
      return ASN1REALLOC (getCtxtPtr (), ptr, numocts);
   }

   /**
    * The memFreePtr method frees the memory at a specific location. This
    * memory must have been allocated using the memAlloc method described
    * earlier.
    *
    * @param ptr          - Pointer to a block of memory allocated with \c
    *                       memAlloc
    */
   inline void memFreePtr (void* ptr) {
      ASN1MEMFREEPTR (getCtxtPtr (), ptr);
   }

   /**
    * The \c Encode method encodes an ASN.1 message using the encoding rules
    * specified by the derived message buffer object.
    */
   virtual int Encode () { return EncodeTo (*mpMsgBuf); }

   /**
    * The \c Decode method decodes the ASN.1 message described by the
    * encapsulated message buffer object.
    */
   virtual int Decode () { return DecodeFrom (*mpMsgBuf); }

   /**
    * The \c EncodeTo method encodes an ASN.1 message into the given message
    * buffer or stream argument.
    *
    * @param msgBuf       - Message buffer or stream to which the message is to
    *                       be encoded.
    */
   virtual int EncodeTo   (ASN1MessageBufferIF& /*msgBuf*/) { return 0; }

   /**
    * The \c DecodeFrom method decodes an ASN.1 message from the given message
    * buffer or stream argument.
    *
    * @param msgBuf       - Message buffer or stream containing message to
    *                       decode.
    */
   virtual int DecodeFrom (ASN1MessageBufferIF& /*msgBuf*/) { return 0; }
} ;
/** @} */

/** 
 * @defgroup asn1data ASN.1 Type (ASN1T_) Base Classes 
 * These classes are used as the base for compiler-generated ASN1T_ C++ data
 * structures. These are enhanced versions of the C structures used for mapping
 * ASN.1 types. The main difference is that constructors and operators have
 * been added to the derived classes. @{
 */
/** 
 * Dynamic bit string. This is the base class for generated C++ data type
 * classes for unsized BIT STRING's.
 */
struct EXTERNRT ASN1TDynBitStr : public ASN1DynBitStr {
   /**
    * The default constructor creates an empty bit string.
    */
   ASN1TDynBitStr () { numbits = 0; }

   /**
    * This constructor initializes the bit string to contain the given data
    * values.
    *
    * @param _numbits     - Number of bits in the bit string.
    * @param _data        - The binary bit data values.
    */
   ASN1TDynBitStr (ASN1UINT _numbits, const ASN1OCTET* _data) { 
      numbits = _numbits; 
      data = _data;
   }

   /**
    * This constructor initializes the bit string to contain the given data
    * values.
    *
    * @param _bs          - C bit string structure.
    */
   ASN1TDynBitStr (ASN1DynBitStr& _bs) { 
      numbits = _bs.numbits; 
      data = _bs.data;
   }
} ;

/** 
 * Dynamic octet string. This is the base class for generated C++ data type
 * classes for unsized OCTET STRING's.
 */
struct EXTERNRT ASN1TDynOctStr : public ASN1DynOctStr {
   /**
    * The default constructor creates an empty octet string.
    */
   ASN1TDynOctStr () { numocts = 0; data = NULL; }

   /**
    * This constructor initializes the octet string to contain the given data
    * values.
    *
    * @param _numocts     - Number of octet in the octet string.
    * @param _data        - The binary octet data values.
    */
   ASN1TDynOctStr (ASN1UINT _numocts, const ASN1OCTET* _data) {
      numocts = _numocts;
      data = _data;
   }

   /**
    * This constructor initializes the octet string to contain the given data
    * values.
    *
    * @param _os          - C octet string structure.
    */
   ASN1TDynOctStr (ASN1DynOctStr& _os) {
      numocts = _os.numocts;
      data = _os.data;
   }

   /**
    * This constructor initializes the octet string to contain the given data
    * values. In this case, it is initializes to contain the characters in a
    * null-terminated C character string.
    *
    * @param cstring      - C null-terminated string.
    */
   ASN1TDynOctStr (const char* cstring) {
      if (strlen(cstring) > 0) {
         numocts = (ASN1UINT)strlen(cstring) + 1;
         data = (const ASN1OCTET*) cstring;
      }
      else numocts = 0;
   }

   /**
    * This assignment operator sets the octet string to contain the characters
    * in a null-terminated C character string. For example, <code>myOctStr = "a
    * char string";</code>
    *
    * @param cstring      - C null-terminated string.
    */
   ASN1TDynOctStr& operator= (const char* cstring) {
      if (strlen(cstring) > 0) {
         numocts = (ASN1UINT)strlen(cstring) + 1;
         data = (const ASN1OCTET*) cstring;
      }
      else numocts = 0;
      return *this;
   }

} ;

/** 
 * Open type. This is the base class for generated C++ data type classes for
 * open type values.
 */
struct EXTERNRT ASN1TOpenType : public ASN1OpenType {
   /**
    * The default constructor creates an empty open type value.
    */
   ASN1TOpenType () { 
      numocts = 0; 
      data = 0;
   }
} ;

/** 
 * Open type with table constraint. This is the base class for generated C++
 * data type classes for open type values with table constraints. It is only
 * used when the -tables compiler command line option is specified.
 */
struct EXTERNRT Asn1TObject : public Asn1Object {
   /**
    * The default constructor creates an empty object value.
    */
   Asn1TObject () { 
      encoded.numocts = 0; 
      encoded.data = 0;
      decoded = 0;
      index =0;
   }
} ;

typedef Asn1TObject ASN1TObject;

/** 
 * Object identifier. This is the base class for generated C++ data type
 * classes for object identifier values.
 */
struct EXTERNRT ASN1TObjId : public ASN1OBJID {
   /**
    * The default constructor creates an empty object identifier value.
    */
   ASN1TObjId () { numids = 0; }

   /**
    * This constructor initializes the object identifer to contain the given
    * data values.
    *
    * @param _numids      - Number of subidentifiers in the OID.
    * @param _subids      - Array of subidentifier values.
    */
   ASN1TObjId (ASN1OCTET _numids, const ASN1UINT* _subids);

   /**
    * This constructor initializes the object identifier to contain the given
    * data values. This can be used to set the value to a compiler-generated
    * OID value.
    *
    * @param oid          - C object identifier value.
    */
   ASN1TObjId (const ASN1OBJID& oid);

   /**
    * The copy constructor.
    *
    * @param oid          - C++ object identifier value.
    */
   ASN1TObjId (const ASN1TObjId& oid);

   /**
    * This assignment operator sets the object identifier to contain the OID in
    * the given C structure. This can be used to set the value to a
    * compiler-generated OID value.
    *
    * @param rhs          - C object identifier value.
    */
   void operator= (const ASN1OBJID& rhs);

   /**
    * This assignment operator sets the object identifier to contain the OID in
    * the given C++ structure.
    *
    * @param rhs          - C++ object identifier value.
    */
   void operator= (const ASN1TObjId& rhs);
} ;

/**
 * Object identifier with 64-bit arcs. This class is identical to the
 * ASN1TObjId class except it allows 64-bit integers to be used for the arc
 * (i.e. subidentifier) values.
 */
struct EXTERNRT ASN1TObjId64 : public ASN1OID64 {
   ASN1TObjId64 () { numids = 0; }
   ASN1TObjId64 (ASN1OCTET _numids, const ASN1INT64* _subids);
   ASN1TObjId64 (const ASN1OID64& oid);
   ASN1TObjId64 (const ASN1TObjId64& oid);
   void operator= (const ASN1OID64& rhs);
   void operator= (const ASN1TObjId64& rhs);
} ;

/**
 * This comparison operator allows for comparison of equality of two C-based
 * object identifier structures.
 *
 * @param lhs          - C object identifier value.
 * @param rhs          - C object identifier value.
 * @return             - True if values are equal.
 */
EXTERNRT int operator== (const ASN1OBJID& lhs, const ASN1OBJID& rhs);

/** 
 * SEQUENCE or SET extension element holder. This is used for the /c extElem1
 * open extension element in extensible SEQUENCE or SET constructs.
 */
struct EXTERNRT ASN1TSeqExt : public Asn1RTDList {
   /**
    * The default constructor creates an empty open extension element.
    */
   ASN1TSeqExt () { 
      rtDListInit (this);
   }
} ;

/** 
 * Base class for PDU types. This class is used as the base class for all
 * compiler-generated PDU types.
 */
struct EXTERNRT ASN1TPDU {
 protected:
   /** 
    * The mpContext member variable holds a smart-pointer to the current
    * context variable. This ensures an instance of this PDU type will persist
    * if the control class and message buffer classes used to decode or copy
    * the message are destroyed.
    */
   ASN1CtxtPtr mpContext;

 public:
   /** 
    * The setContext method allows the context member variable to be set. It is
    * invoked in compiler-generated control class decode and copy methods.
    */
   inline void setContext (ASN1Context* ctxt) {
      if (mpContext.data () == 0) mpContext = ctxt;
   }
   inline void unsetContext () {
      if (mpContext.data () != 0) mpContext.data()->_unref();
   }
} ;

/** 
 * SEQUENCE OF element holder. This class is used as the base class for
 * compiler-generated SEQUENCE OF linked-list types.
 */
struct EXTERNRT ASN1TSeqOfList : public Asn1RTDList {
   /**
    * The default constructor creates an empty list.
    */
   ASN1TSeqOfList () { 
      rtDListInit (this);
   }
} ;

/** 
 * SEQUENCE OF element holder (PDU). This class is used as the base class for
 * compiler-generated SEQUENCE OF linked-list types. In this case, the type has
 * also been determined to be a PDU.
 */
struct EXTERNRT ASN1TPDUSeqOfList : public ASN1TSeqOfList, public ASN1TPDU {
   /**
    * The default constructor creates an empty list.
    */
   ASN1TPDUSeqOfList () {} 
} ;
/** @} */

/** @} */

#endif
