/*
 * 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
// 11/03/03	CZ	Expand documentation comments.
//
///////////////////////////////////////////////////////////////
*/

/** 
 * @file asn1XerCppTypes.h 
 * XER C++ type and class definitions.
 */
#ifndef _ASN1XERCPPTYPES_H_
#define _ASN1XERCPPTYPES_H_

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

#include "rtxersrc/saxParser.h"
#include "rtsrc/asn1CppTypes.h"
#include "rtsrc/OSCInputStream.h"
#include "rtxersrc/asn1xer.h"

/** @defgroup xercppruntime XER C++ Runtime Classes.
 * @{
 */

#ifndef _NO_EXCEPTIONS
#ifdef _TRACE

#define ASN1SAXTHROW(stat) throwSAXException (stat, __FILE__, __LINE__);

#define ASN1SAXCATCH0(toCatch,stat) \
   catch (OSRTSAXException& toCatch) { \
      cerr << "ASN1XERSAX ERROR: "; \
      if (toCatch.getMessage()) \
         cerr << StrX (toCatch.getMessage()); \
      stat = toCatch.getStatus(); \
      if (stat) \
         cerr << "\n" << "Status: " << stat << endl; \
      if (toCatch.getSrcFileName ()) {\
         cerr  << "File: " << StrX (toCatch.getSrcFileName ()); \
         cerr << " Line: " << toCatch.getSrcLineNum () << endl; \
      } \
   } 
#else

#define ASN1SAXTHROW(stat) throwSAXException (stat);

#define ASN1SAXCATCH0(toCatch,stat) \
   catch (OSRTSAXException& toCatch) { \
      cerr << "ASN1XERSAX ERROR: "; \
      if (toCatch.getMessage()) \
         cerr << StrX (toCatch.getMessage()); \
      stat = toCatch.getStatus(); \
      if (stat) \
         cerr << "\n" << "Status: " << stat << endl; \
   } 
#endif

#define ASN1SAXCATCH(toCatch,stat) \
   ASN1SAXCATCH0(toCatch,stat) \
   catch (const ASN1MessageBuffer::RTLError& toCatch) { \
      cerr << "ASN.1 RTL ERROR: " << toCatch.getStatus() << endl; \
      stat = toCatch.getStatus(); \
   }
#else
#define ASN1SAXTHROW(stat) { \
fprintf (stderr, "Fatal Error %i in %s at %i\n", stat, __FILE__, __LINE__); \
exit (-1); \
}
#define ASN1SAXCATCH(toCatch,stat)
#endif

/** @defgroup xermsgbuffclas XER Message Buffer Classes
 * These classes manage the buffers for encoding and decoding ASN.1 XER 
 * messages.
 * @{
*/


// ASN.1 XER message buffer class

/**
 * The XER message buffer class is derived from the ASN1MessageBuffer
 * base class. It is the base class for the ASN1XEREncodeBuffer
 * and ASN1XERDecodeBuffer classes. It contains variables and methods
 * specific to encoding or decoding ASN.1 messages using the XML 
 * Encoding Rules (XER). It is used to manage the buffer into which an 
 * ASN.1 message is to be encoded or decoded.
 *
 */
class EXTERNXER ASN1XERMessageBuffer : public ASN1MessageBuffer {
 protected:
   /**
    * 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, XEREncode or XERDecode).
    */
   ASN1XERMessageBuffer (Type bufferType) : ASN1MessageBuffer(bufferType) {}
 public:
} ;

// ASN.1 XER encode message buffer class
 /**
 * The ANS1XEREncodeBuffer class is derived from the ASN1XERMessageBuffer base 
 * class. It contains variables and methods specific to encoding ASN.1 messages
 * using the XML Encoding Rules (XER). It is used to manage the buffer into 
 * which an ASN.1 message is to be encoded.
 * 
 */

class EXTERNXER ASN1XEREncodeBuffer : public ASN1XERMessageBuffer {
 public:
/**
 * Default constructor
 */
   ASN1XEREncodeBuffer ();
/**
 * A constructor
 *
 * @param canonical Indicates the usage of Canonical XER(CXER).
 */
   ASN1XEREncodeBuffer (ASN1BOOL canonical);
/**
 * A constructor
 *
 * @param canonical Indicates the usage fo Canonical XER(CXER).
 * @param pSrcCtxt    Source context; its memory heap will be used.
 * @param initBufSize Initial size of encode buffer
*/
   ASN1XEREncodeBuffer (ASN1BOOL canonical, ASN1CTXT* pSrcCtxt, 
      int initBufSize = 0);
/**
* A constructor
*
* @param pMsgBuf  A pointer to a fixed size message buffer to receive
*                 the encoded message.
*
* @param msgBufLen Size of the fixed-size message buffer.
*
*/
   ASN1XEREncodeBuffer (ASN1OCTET* pMsgBuf, int msgBufLen);

/**
* A constructor
*
* @param pMsgBuf  A pointer to a fixed size message buffer to receive
*                 the encoded message.
*
* @param msgBufLen Size of the fixed-size message buffer.
*
* @param canonical Indicates the usage fo Canonical XER(CXER).
*
* @param openType Open Type encoding indicator. Set this argument
                   as TRUE to encode an open type.
*/

   ASN1XEREncodeBuffer (ASN1OCTET* pMsgBuf, int msgBufLen, 
                        ASN1BOOL canonical, ASN1BOOL openType = FALSE);
/**
*This method returns the length of a previously encoded XER message.
* 
* @return len Length of the XER message encapsulated within this buffer object.
*/
   inline int getMsgLen () { 
      return (getCtxtPtr()->buffer.byteIndex);
   }
/**
 *This method reinitializes the encode buffer pointer to 
 * allow a new message to be encoded.  This makes it possible
 * to reuse one message buffer object in a loop to encode
 * multiple messages.  After this method is called, any 
 * previously encoded message in the buffer will be overwritten
 * on the next encode call.
 */
   void init ();
   virtual ASN1BOOL isA (Type bufferType) {
      return bufferType == XEREncode;
   }
 /**
 *
 * This method turns Canonical XML Encoding Rules (CXER) usage on.
 * 
 * 
 */
   inline void setCanonical() { rtCtxtSetFlag (getCtxtPtr(), ASN1CANXER); }

/**
 * 
 * This method turns Open Type encoding on.
 * 
*/
   inline void setOpenType () { rtCtxtSetFlag (getCtxtPtr(), ASN1OPENTYPE); }
/**
 * There are two versions of this method. The first version writes
 *  to a file that is specified by file name.
 * 
 * 
 * @return           Number of octets actually written, which may be
 *                    less than real message length if an error occurs. 
 *
 * @param  filename The name of file for writing the encoded message.

*/
   int write (const char* filename);
/**
* The second version writes to a file that is specified by a FILE pointer.

 * @return           Number of octets actually written, which may be
 *                    less than real message length if an error occurs.

 * @param  fp       The pointer to FILE structure for writing the encoded
 *                  message.
 * 
*/
   int write (FILE* fp);
} ;

//XER SAX decode handler base class. ASN1XERSAXDecodeHandler derived class. 
 /**
 * 
 * This class is derived from the SAX class DefaultHandler base class. 
 * It contains variables and methods specific to XML decoding ASN.1 messages. 
 * It is used to intercept standard SAX parser events, such as startElement,
 * characters, endElement. This class is used as a base class for XER ASN1C 
 * generated ASN1C_* classes.
*/ 
class EXTERNXER ASN1XERSAXDecodeHandler : 
   public OSXMLContentHandler, public OSXMLErrorInfo 
{
 protected:
   ASN1XERState mCurrState;
   int mCurrElemID;
   int mLevel, mStartLevel;
   const char* mpTypeName;
   struct ErrorInfo {
      int stat;
      const char* file;
      int line;
   } errorInfo;
 public:

/**
* Default constructor without parameters.
*/
   ASN1XERSAXDecodeHandler () : 
	mCurrState(XERINIT), mCurrElemID(0), mLevel(0), mStartLevel(0), mpTypeName(0)
    {
	errorInfo.stat = 0;
	errorInfo.file = NULL;
	errorInfo.line = 0;
    }

   virtual void startElement 
      (const XMLCHAR* const uri, 
       const XMLCHAR* const localname, 
       const XMLCHAR* const qname, 
       const XMLCHAR* const* attrs);

   virtual void characters 
      (const XMLCHAR* const chars, const unsigned int length);

   virtual void endElement
      (const XMLCHAR* const uri,
       const XMLCHAR* const localname,
       const XMLCHAR* const qname);

   virtual void startDocument();
   virtual void endDocument ();

   // SAX Error Info handlers
   virtual void resetErrorInfo ();
   virtual void setErrorInfo (int status, const char* file = 0, int line = 0);
   virtual int  getErrorInfo (int* status, const char** file, int* line);

   // SAX ErrorHandler interface

   // void warning (const SAXParseException& exception);
   // void error (const SAXParseException& exception);
   // void fatalError (const SAXParseException& exception);
   // void resetErrors ();

  /**
 * This method returns the current state of the decoding process.
 *	
 * @return   The state of the decoding process as type ASN1XERState. Can be
 *            XERINIT, XERSTART, XERDATA, or XEREND.
 *
 * @param   -none
 */
  inline ASN1XERState getState() { return mCurrState; }
   virtual void finalize() {}
   ASN1CTXT* finalizeMemBuf(ASN1MessageBufferIF* msgBuf, ASN1MemBuf& memBuf);
   virtual void init (int level = 0) {
      mCurrState = XERINIT; mStartLevel = mLevel = level;
   }
 /** 
 * This method returns the completion status of the decoding process.
 * 
 * @return   The completion state of decoding process, as ASN1BOOL. 
             Can be TRUE (completed) or FALSE (not completed).
 */
   inline ASN1BOOL isComplete ()  { return mLevel == mStartLevel; }
   void setTypeName (const char* typeName) {
      mpTypeName = typeName;
   }
   virtual void throwSAXException (int stat, const char* file = 0, 
      int line = 0);
} ;


// ASN.1 XER Decode Message Buffer Class
/**
 * The ANS1XERDecodeBuffer class is derived from the ASN1XERMessageBuffer base 
 * class. It contains variables and methods specific to decoding ASN.1 XER 
 * messages. It is used to manage the input buffer containing an ASN.1 message 
 * to be decoded. 
 *
 * Note that the XER decode buffer object does not take a message 
 * buffer argument because buffer management is handled by the XML parser.
 *
*/
class EXTERNXER ASN1XERDecodeBuffer : public ASN1XERMessageBuffer {
 protected:
   union {
#if !defined NO_ASN1_RT_REDUNDANT
      const char* fileName;
      OSCInputStream* pInputStream;
#endif	/* !NO_ASN1_RT_REDUNDANT */
      struct {
         const ASN1OCTET* pMemBuf;
         int              bufSize;
      } memBuf;
   } mInput;
   enum {
#if !defined NO_ASN1_RT_REDUNDANT
      INPUT_FILE,
      INPUT_STREAM,
      INPUT_STREAM_ATTACHED,
#endif	/* !NO_ASN1_RT_REDUNDANT */
      INPUT_MEMORY
   } mInputId;
 public:

 /**
 * The ASN1XERDecodeBuffer class has three overloaded constructors.
 *  This version of the ASN1XERDecodeBuffer constructor takes a name of a 
 *  file that contains the XML data to be decoded, and constructs a buffer.

 * @param xmlFile  A pointer to name of file to be decoded.
 */
#if !defined NO_ASN1_RT_REDUNDANT
   ASN1XERDecodeBuffer (const char* xmlFile);
#endif	/* !NO_ASN1_RT_REDUNDANT */

/**
* This version of the ASN1XERDecodeBuffer constructor takes parameters
* describing the message to be decoded, and constructs a buffer describing
* an encoded ASN.1 message.
 *@param  msgbuf   A pointer to a buffer containing an encoded ASN.1 message.
* @param numocts   Size of the message buffer.
* @param openType Open Type decoding indicator. Set this argument
                   as TRUE to decode an open type.
*/
   ASN1XERDecodeBuffer (const ASN1OCTET* msgbuf, 
                        ASN1UINT numocts, 
                        ASN1BOOL openType = FALSE, 
                        ASN1Context * ctxt = NULL);

 /**
 * This version of the ASN1XERDecodeBuffer constructor takes
 * a reference to the OSCInputStream object.
 * @param inputStream  reference to the OSCInputStream object
 *
 * @param openType Open Type decoding indicator. Set this argument
                    as TRUE to decode an open type.
 */
#if !defined NO_ASN1_RT_REDUNDANT
   ASN1XERDecodeBuffer (OSCInputStream& inputStream, 
                        ASN1BOOL openType = FALSE);
#endif	/* !NO_ASN1_RT_REDUNDANT */

   ~ASN1XERDecodeBuffer ();

 /**
 * This method decodes an XML message associated with this buffer. 
 * 
 *
 * @return stat             Status of the operation.  Possible values 
 *                          are ASN_OK if successful or one of the negative
 *                          error status codes defined in Appendix A of the
 *                          C/C++ runtime Common Functions Reference Manual.
 * @param pReader          Pointer to OSXMLReader object.
 *
 */
   int decodeXML (OSXMLReader* pReader);

/**
 * This method returns the name of the XML file that is associated 
 * with the current buffer.
 * 
 *
 * @return  Name of the XML file that is associated with the current buffer.
 * 
 */
#if !defined NO_ASN1_RT_REDUNDANT
   inline const char* getXmlFileName() { 
      return (mInputId == INPUT_FILE) ? mInput.fileName : 0; 
   }
#endif	/* !NO_ASN1_RT_REDUNDANT */

 /**
 * This method reinitializes the decode buffer pointer to allow 
 * new data to be decoded. This makes it possible to reuse 
 * one message buffer object in a loop to decode multiple 
 * data messages.
 * 
 * @return    Status of the operation.  Possible values are ASN_OK if 
 *            successful or one of the negative error status codes defined
 *            in Appendix A of the C/C++ Run-time Common Functions Reference
 *            Manual.
 * @param    membuf reference to ASN1MemBuf object.
 * 
 */
   int initBuffer (ASN1MemBuf& membuf) {
      return ASN1XERMessageBuffer::initBuffer (membuf);
   }

#ifdef XML_UNICODE
   int initBuffer (ASN116BITCHAR* unistr);
   int initBuffer (char* str) { (void)str; return ASN_E_NOTSUPP; }
#else
   int initBuffer (char* str);
   int initBuffer (ASN116BITCHAR* str) { (void)str; return ASN_E_NOTSUPP; }
#endif

   virtual ASN1BOOL isA (Type bufferType) {
      return bufferType == XERDecode;
   }
   virtual void throwSAXException (int stat, const char* file = 0, 
      int line = 0);

   inline void setOpenType () { rtCtxtSetFlag (getCtxtPtr(), ASN1OPENTYPE); }
} ;

/** 
* @} xermsgbuffclas
*/

/** 
 * @}asn1XerCppTypes
 */


#endif // _ASN1XERCPPTYPES_H_




