/*
 * 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
// 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.
// 10/30/03    CZ      Added Doxygen code.
//
////////////////////////////////////////////////////////////////////////////

/** 
 * @file asn1BerCppTypes.h 
 * BER/DER C++ types' and classes' definitions.
 */
#ifndef _ASN1BERCPPTYPES_H_
#define _ASN1BERCPPTYPES_H_

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

#include "asn1CppTypes.h"
#include "asn1ber.h"

/** @defgroup bercppruntime BER C++ Run-Time Classes.
 * @{
 */


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

// ASN.1 BER message buffer class

/**
 * The ASN1BERMessageBuffer class is derived from the ASN1MessageBuffer
 * base class. It is the base class for the ASN1BEREncodeBuffer and  
 * ASN1BERDecodeBuffer derived classes. It contains variables and methods
 * specific to encoding or decoding ASN.1 messages using the Basic 
 * Encoding Rules(BER) and Distinguished Encoding Rules (DER).It is 
 * used to manage the buffer into which an ASN.1 message is to be 
 * encoded or decoded.
*/

class EXTERNBER ASN1BERMessageBuffer : 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, BEREncode or BERDecode).
    */
   ASN1BERMessageBuffer (Type bufferType) : ASN1MessageBuffer(bufferType) {}

 public:
 /**
 * This method calculates the actual length of an indefinite length message
 * component.
 *
 * Calling Sequence: 
 *
 * <TT>len=messageBuffer.calcIndefLen (buf_p);</TT>
 *
 * where messageBuffer is an ASN1BERMessageBuffer derived class object.
 *
 * @return            Length, in octets, of message component, as int. 
 *  
 * @param    buf_p     A pointer to a message component encoded 
 *                     using indefinite length encoding.
 * @param    bufSize   Size of the buffer \c buf_p (in octets). 
 *
 */
#if !defined NO_ASN1_RT_REDUNDANT
   inline int calcIndefLen (ASN1OCTET* buf_p, int bufSize = INT_MAX) {
      return xd_indeflen_ex (buf_p, bufSize);
   }
#endif	/* !NO_ASN1_RT_REDUNDANT */

 /**
 * This method outputs a formatted binary dump of the current buffer 
 * contents to stdout.
 *
 * Calling Sequence: 
 *
 * <TT>messageBuffer.binDump ();</TT>
 *
 * where messageBuffer is an ASN1BERMessageBuffer derived class object.
 */
#if !defined NO_ASN1_RT_REDUNDANT
   inline void binDump () { 
      xu_dump ((ASN1OCTET*)GetMsgPtr(), 0, 0); 
   }
#endif	/* !NO_ASN1_RT_REDUNDANT */

 /**
 * This method outputs a hexadecimal dump of the current buffer contents
 *  to stdout.
 * 
 * Calling sequence:
 *
 * <TT>messageBuffer.hexDump ();</TT>
 *
 * where messageBuffer is an ASN1BERMessageBuffer derived class object. 
*/
#if !defined NO_ASN1_RT_REDUNDANT
   inline void hexDump (int numocts) { 
      xu_hex_dump ((ASN1OCTET*)GetMsgPtr(), numocts, TRUE); 
   }
#endif	/* !NO_ASN1_RT_REDUNDANT */

   // deprecated methods
#if !defined NO_ASN1_RT_REDUNDANT
   inline int  CalcIndefLen (ASN1OCTET* buf_p) { return calcIndefLen(buf_p); }
   inline void BinDump () { binDump(); }
   inline void HexDump (int numocts) { hexDump (numocts); }
#endif	/* !NO_ASN1_RT_REDUNDANT */
} ;

// ASN.1 BER encode message buffer class
 /**
 * The ANS1BEREncodeBuffer class is derived from the ASN1BERMessageBuffer base 
 * class. It contains variables and methods specific to encoding ASN.1 messages 
 * using the Basic Encoding Rules (BER). It is used to manage the buffer into 
 * which an ASN.1 message is to be encoded.
 */
class EXTERNBER ASN1BEREncodeBuffer : public ASN1BERMessageBuffer {
 public:
 /**
 * A Constructor. ASN1BEREncodeBuffer has 2 overloaded constructors.
 * This version tales no arguments (dynamic encoding version).
 *   
 */
   ASN1BEREncodeBuffer ();
 /**
 * A Constructor. ASN1BEREncodeBuffer has 2 overloaded constructors.
 * This version takes a message buffer ans size argument (static encoding version)
 *
 * @param  pMsgBuf       A pointer to a fixed size message buffer to recieve the encoded
 *                      message.
 * @param  msgBufLen     Size of the fixed-size message buffer.
 * 
 */
   ASN1BEREncodeBuffer (ASN1OCTET* pMsgBuf, int msgBufLen);

 /** 
 * This method returns a copy of the current encoded message. 
 * Memory is allocated for the message using the 'new' operation. It is the users's  *  *responsibility to free the memory using 'delete.'
 * 
 * Calling Sequence:
 * 
 * <TT>ptr = encodeBuffer.getMsgCopy ();</TT>
 * 
 *  where encodeBuffer is an ASN1BEREncodeBuffer object.
 *
 * @return    Pointer to copy of encoded message. It is the users's  
 *            responsibility to free the memory using 'delete' 
 *            (i.e., delete [] ptr;).
 *
 */
   virtual ASN1OCTET* getMsgCopy ();

 /**
 * This methode returns the internal pointer to the current encoded massage.
 * Calling Sequence:
 * 
 *    <TT>ptr = encodeBuffer.getMsgPtr ();</TT>
 * 
 *  where encodeBuffer is an ASN1BEREncodeBuffer object.
 * 
 *  @return    Pointer to encoded message.
 * 
 */
   virtual const ASN1OCTET* getMsgPtr ();

 /** 
 * 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.
 *  
 * Calling Sequence:
 * 
 * 	<TT>encodeBuffer.init ();</TT>
 * 
 * where encodeBuffer is an ASN1BEREncodeBuffer object.
 * 
 */
   void init ();

   virtual ASN1BOOL isA (Type bufferType) {
      return bufferType == BEREncode;
   }
   int setBuffer (ASN1OCTET* pMsgBuf, int msgBufLen);

   ASN1BEREncodeBuffer& operator << (ASN1CType& val); 
} ;


// ASN.1 BER decode message buffer class
/**
 * The ANS1BERDecodeBuffer class is derived from the ASN1BERMessageBuffer base 
 * class. It contains variables and methods specific to decoding ASN.1 BER/DER 
 * messages. It is used to manage the input buffer containing an ASN.1 message 
 * to be decoded.
*/

class EXTERNBER ASN1BERDecodeBuffer : public ASN1BERMessageBuffer {
 protected:
   const ASN1OCTET* mpMsgBuf;
   int mMsgBufLen;
   ASN1BOOL mBufSetFlag;

 public:
 /**
 * A Constructor
 * 
 */
   ASN1BERDecodeBuffer ();

 /**
 * Constructor for ASN1BERDecodeBuffer constructs a buffer describing 
 * an encoded ASN.1 message.  Parameters describing the message to be 
 * decoded are passed as arguments. 
 *
 * @param pMsgBuf          A pointer to a buffer containing an encoded 
 *                         ASN.1 message.
 * 
 * @param msgBufLen        Size of the message buffer.  This does not 
 *                         have to be equal to the length of the message.  
 *                         The message length can be determined from the outer
 *                         tag-length-value in the message.  This parameter
 *                         is used to determine if the length of the message is
 *                         valid; therefore it must be greater than or equal to 
 *                         the actual length.  Typically, the size of the buffer 
 *                         the message was read into is passed.
 */
   ASN1BERDecodeBuffer (const ASN1OCTET* pMsgBuf, int msgBufLen);

 /**
 * This method finds a tagged element within a message. 
 * 
 * Calling Sequence:
 * 
 * 	<TT>ptr = decodeBuffer.findElement (tag, elemLen, firstFlag);</TT>
 * 
 * where decodeBuffer is an ASN1BERDecodeBuffer object.
 *  
 * @return              Pointer to tagged component in message or NULL if  
 *                      component not found.
 * 
 * @param   tag          ASN.1 tag value to search for.
 *
 * @param   firstFlag    Flag indicating if this the first time this search 
 *                       is being done.  If true, internal pointers will 
 *                       be set to start the search from the beginning of
 *                       the message.  If false, the search will be 
 *                       resumed from the point at which the last matching 
 *                       tag was found.  This makes it possible to find all
 *                      instances of a particular tagged element within a
 *                       message 
 * @param  elemLen      Reference to an integer value to receive the length 
 *                      of the found element.
 */

   ASN1OCTET* findElement (ASN1TAG tag, int& elemLen, int firstFlag = 1);

   void init () { setBuffer (mpMsgBuf, mMsgBufLen); }

   virtual ASN1BOOL isA (Type bufferType) {
      return bufferType == BERDecode;
   }
 /**
 * This method will parse the initial tag-length pair from the message.
 * 
 * Calling Sequence:
 * 
 * 	<TT>stat = decodeBuffer.parseTagLen (tag, msglen);</TT>
 * 
 * where decodeBuffer is an ASN1BERDecodeBuffer object.
 * 
 * @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++ Common Functions Reference Manual.
 * 
 * @param    tag      Reference to a tag structure to receive the outer
 *                    level tag value parsed from the message.
 * 
 * @param    msglen  Length of the message. This is the total length
 *                   of the message obtained by adding the number of
 *                   bytes in initial tag-length to the parsed length 
 *                   value.
 */
   inline int parseTagLen (ASN1TAG& tag, int& msglen) {
      if (!mpMsgBuf || mMsgBufLen <= 0)
	  return ASN_E_NOTSUPP;
      mBufSetFlag = TRUE;
      return xd_setp (mpContext->GetPtr(), 
                      mpMsgBuf, mMsgBufLen, &tag, &msglen);
   }

#if !defined NO_ASN1_RT_REDUNDANT
   int readBinaryFile (const char* filePath);
#endif	/* !NO_ASN1_RT_REDUNDANT */

   int setBuffer (const ASN1OCTET* pMsgBuf, int msgBufLen,
       ASN1BOOL enableOptimization = TRUE);

   // deprecated methods
   inline ASN1OCTET* FindElement (ASN1TAG tag, int& elemLen, 
                                  int firstFlag = 1) {
      return findElement (tag, elemLen, firstFlag);
   }
   inline int ParseTagLen (ASN1TAG& tag, int& msglen) {
      return parseTagLen (tag, msglen);
   }

   ASN1BERDecodeBuffer& operator >> (ASN1CType& val); 
} ;

/** 
* @} bermsgbuffclas
*/

/** 
* @} bercppruntime
*/
#endif
