/*
 * 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
// 05/03/02     AB      Initial issue
// 05/06/02     AB      More only-BER things moved
// 05/10/02     AB      RELATIVE-OID
// 10/17/02     ED      Inline buffer save and restore macros
// 10/26/02     AB      UInt64 encode/decode funcs added
// 01/18/03	ED	Added more Doxygen comments
// 10/29/03     CZ      Added doxygen code for mainpage text.
//
////////////////////////////////////////////////////////////////////////////
*/
/** 
 * @file asn1ber.h 
 * ASN.1 runtime constants, data structure definitions, and functions to
 * support the Basic Encoding Rules (BER) and Distinguished Encoding Rules
 * (DER) as defined in the ITU-T X.690 standard.
 */

/**

 *
 * @mainpage ASN1C BER/DER Runtime Classes and Library Functions
 *
 * 
 * The <B>ASN.1 C++ Runtime Classes</B> are wrapper classes that provide
 * an object-oriented interface to the ASN.1 C runtime library functions.
 * The classes described in this manual are derived from the common 
 * classes documented in the ASN1C C/C++ Common Runtime manual. 
 * They are specific to the Basic Encoding Rules (BER) and Distinguished 
 * Encoding Rules (DER) as defined in the ITU-T X.690 standard. 
 * 
 * These BER/DER specific C++ runtime classes include:
 * <UL> <LI>classes for streaming BER/DER decoding </LI><LI>classes for 
 * streaming BER/DER encoding.</LI></UL>
 *
 *
 * The <B> ASN.1 BER Runtime Library</B> contains all of the
 * low-level constants, types, and functions that are assembled by the compiler
 * to encode/decode more complex structures.
 *
 * This library consists of the following two items:
 *   <UL> <LI>A global include file ("asn1ber.h") that is compiled into all
 * generated source files.</LI>
 *<LI> An object library of functions that are linked with the C functions
 * after compilation with a C complier.</LI></UL>
 *
 * In general, programmers will not need to be too concerned with the details
 * of these functions. The ASN.1 compiler generates calls to them in the C or
 * C++ source files that it creates. However, the functions in the library may
 * also be called on their own in applications requiring their specific
 * functionality.
 */

/** @defgroup berruntime BER Runtime Library Functions.
 * @{
 *
 * The ASN.1 Basic Encoding Rules (BER) Runtime Library contains the
 * low-level constants, types, and functions that are assembled by the compiler
 * to encode/decode more complex structures.
 *

 */
#ifndef _ASN1BER_H_
#define _ASN1BER_H_

#include "asn1type.h"

#define ASN1BUF_SAVE(cp) { \
(cp)->savedInfo.byteIndex = (cp)->buffer.byteIndex; \
(cp)->savedInfo.flags = (cp)->flags; }

#define ASN1BUF_RESTORE(cp) { \
(cp)->buffer.byteIndex = (cp)->savedInfo.byteIndex; \
(cp)->flags = (cp)->savedInfo.flags; }

#define XU_DUMP(msg)            xu_dump(msg,0,0)
#define xd_resetp(ctxt_p)       rtResetContext(ctxt_p)

#define ASN1TAG2BYTE(tag) \
((ASN1OCTET)(((tag)&TM_B_IDCODE)|((tag)>>ASN1TAG_LSHIFT)))



/** 
 Buffer location descriptor 

*/
typedef struct _Asn1BufLocDescr {
   ASN1UINT numocts;
   ASN1INT  offset;
} Asn1BufLocDescr;

#ifdef __cplusplus
extern "C" {

#endif

#ifndef EXTERNBER
#ifdef BUILDASN1BERDLL
#define EXTERNBER __declspec(dllexport)
#elif defined (USEASN1BERDLL)
#define EXTERNBER __declspec(dllimport)
#else
#define EXTERNBER
#endif /* BUILDASN1BERDLL */
#endif /* EXTERNBER */

/* decode functions */
/** @defgroup berdecruntime BER/DER C Decode Functions.
 * @{
 *
 * BER/DER C decode functions handle the decoding of the primitive ASN.1 data
 * types and ASN.1 length and tag fields within a message. Calls to these
 * functions are assembled in the C source code generated by the ASN1C compiler
 * to decode complex ASN.1 structures. These functions are also directly
 * callable from within a user's application program if the need to decode a
 * primitive data item exists.
 *
 * The procedure to decode a primitive data item is as follows:
 *   -# Call the xd_setp low-level decode function to specify the address of
 * the buffer containing the encoded ASN.1 data to be decoded.
 *   -# Call the specific decode function to decode the value. The tag value
 * obtained in the first step can be used to determine which decode function to
 * call for decoding the variable.
 */

/**
 * This function decodes an ASN.1 tag into a standard 32-bit unsigned integer
 * type. The bits used to represent the components of a tag are as follows:
 *
 * Bit Fields:
 *   - 31-30 Class (00 = UNIV, 01 = APPL, 10 = CTXT, 11 = PRIV)
 *   - 29 Form (0 = primitive, 1 = constructed)
 *   - 28-0 ID code value
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tag_p        Pointer to variable to receive decoded tag info.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNBER int xd_tag (ASN1CTXT* ctxt_p, ASN1TAG *tag_p);

/**
 * This function parses the ASN.1 tag and length fields located at the current
 * message pointer position.
 *
 * xd_tag_len monitors indefinite length messages as follows: Each time a
 * length is parsed, it is checked to see if it is an indefinite length value.
 * If it is, an indefinite length section counter is incremented. Each time an
 * end-of-contents (EOC) identifier is parsed, this counter is decremented.
 * When the counter goes to zero, end of message is signaled.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tag_p        Pointer to variable to receive decoded tag info.
 * @param len_p        Length of message component. Returned as follows: >= 0
 *                       component is fixed length ASN_K_INDEFLEN component is
 *                       indefinite length
 * @param flags        Bit flags used to set the following options: XM_ADVANCE:
 *                       Advance decode pointer on match.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNBER int xd_tag_len (ASN1CTXT *ctxt_p, ASN1TAG *tag_p, 
                          int *len_p, ASN1OCTET flags);

/**
 * This function compares the tag at the current message pointer position with
 * the given tag for a match. If a match occurs, the length field is decoded
 * and the length is returned to the caller. If the input parameter 'advance'
 * is set to TRUE, the message pointer is advanced to the beginning of the
 * contents field.
 *
 * If a match does not occur, the routine will skip to subsequent fields in
 * search of a match. If a match is eventually found, the processing described
 * above is done; otherwise, a not found status is returned to the caller.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tag          Tag variable to match.
 * @param len_p        Length of message component. Returned as follows: >= 0
 *                       component is fixed length ASN_K_INDEFLEN component is
 *                       indefinite length
 * @param flags        Bit flags used to set the following options:
 *                       - XM_ADVANCE: Advance decode pointer on match.
 *                       - XM_SEEK : Seek until match found or EOM.
 *                       - XM_SKIP : Skip to next tag before search
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_match (ASN1CTXT *ctxt_p, ASN1TAG tag, 
                        int *len_p, ASN1OCTET flags);

/**
 * This function parses an ASN.1 BOOLEAN tag/length/value at the current
 * message pointer location and advances the pointer to the next field.
 *
 * The function first checks to see if explicit tagging is specified. If yes,
 * the universal tag for this message type is checked to make sure it is of the
 * expected value. If the match is not successful, a negative value is returned
 * to indicate the parse was not successful. Otherwise, the pointer is advanced
 * to the length field and the length parsed.
 *
 * The length value is then check to see if it is equal to one which is the
 * only valid length for boolean. If it is equal, the boolean data value is
 * parsed; otherwise, and error is returned.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Decoded boolean data value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - ASN_E_INVLEN invalid length (!= 1)
 *                       - ASN_E_IDNOTFOU unexpected tag value (not UNIV 1)
 */
EXTERNBER int xd_boolean (ASN1CTXT *ctxt_p, ASN1BOOL *object_p, 
                          ASN1TagType tagging, int length);

/**
 * This function parses an ASN.1 INTEGER tag/length/value at the current
 * message pointer location and advances the pointer to the next field.
 *
 * The function first checks to see if explicit tagging is specified. If yes,
 * the universal tag value is parsed and checked to make sure it matches the
 * expected tag for this message type. If not, a negative value is returned to
 * indicate the parse was not successful. Otherwise, the length value is
 * parsed.
 *
 * If the match is successful or implicit tagging is specified, the integer
 * data value is parsed.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to decoded integer value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_integer (ASN1CTXT *ctxt_p, ASN1INT *object_p, 
                          ASN1TagType tagging, int length);

/**
 * This function parses an ASN.1 INTEGER tag/length/value at the current
 * message pointer location and advances the pointer to the next field.
 *
 * This function is similar to ::xd_integer but it is used to parse 8-bit
 * integer values.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to decoded 8-bit integer value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_int8 (ASN1CTXT *ctxt_p, ASN1INT8 *object_p, 
                       ASN1TagType tagging, int length);

/**
 * This function parses an ASN.1 INTEGER tag/length/value at the current
 * message pointer location and advances the pointer to the next field.
 *
 * This function is similar to ::xd_integer but it is used to parse 16-bit
 * integer values.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to decoded 16-bit integer value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_int16 (ASN1CTXT *ctxt_p, ASN1SINT *object_p, 
                        ASN1TagType tagging, int length); 

/**
 * This function parses an unsigned variant of ASN.1 INTEGER tag/length/value
 * at the current message pointer location and advances the pointer to the next
 * field.
 *
 * The function first checks to see if explicit tagging is specified. If yes,
 * the universal tag value is parsed and checked to make sure it matches the
 * expected tag for this message type. If not, a negative value is returned to
 * indicate the parse was not successful. Otherwise, the length value is
 * parsed.
 *
 * If the match is successful or implicit tagging is specified, the integer
 * data value is parsed.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to decoded unsigned integer value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_unsigned (ASN1CTXT *ctxt_p, ASN1UINT *object_p, 
                           ASN1TagType tagging, int length);

/**
 * This function parses an unsigned variant of ASN.1 INTEGER tag/length/value
 * at the current message pointer location and advances the pointer to the next
 * field.
 *
 * This function is similar to ::xd_unsigned but it is used to parse 8-bit
 * unsigned integer values.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to decoded 8-bit unsigned integer value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_uint8 (ASN1CTXT *ctxt_p, ASN1UINT8 *object_p, 
                        ASN1TagType tagging, int length); 

/**
 * This function parses an unsigned variant of ASN.1 INTEGER tag/length/value
 * at the current message pointer location and advances the pointer to the next
 * field.
 *
 * This function is similar to ::xd_unsigned but it is used to parse 16-bit
 * unsigned integer values.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to decoded 16-bit unsigned integer value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_uint16 (ASN1CTXT *ctxt_p, ASN1USINT *object_p, 
                         ASN1TagType tagging, int length); 

/**
 * This function parses an ASN.1 INTEGER tag/length/value at the current
 * message pointer location and advances the pointer to the next field.
 *
 * The function is similar to ::xd_integer but it can be used to parse integer
 * values with sizes up to 64 bits (if platform supports such integer's size).
 *
 * If the match is successful or implicit tagging is specified, the integer
 * data value is parsed.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to decoded 64-bit integer value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_int64 (ASN1CTXT *ctxt_p, ASN1INT64 *object_p, 
                        ASN1TagType tagging, int length);

/**
 * This function parses an unsigned variant of ASN.1 INTEGER tag/length/value
 * at the current message pointer location and advances the pointer to the next
 * field.
 *
 * The function is similar to ::xd_unsigned but it can be used to parse integer
 * values with sizes up to 64 bits (if platform supports such integer's size).
 *
 * If the match is successful or implicit tagging is specified, the integer
 * data value is parsed.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to decoded 64-bit unsigned integer value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_uint64 (ASN1CTXT *ctxt_p, ASN1UINT64 *object_p, 
                         ASN1TagType tagging, int length);

/**
 * This function parses an ASN.1 INTEGER tag/length/value at the current
 * message pointer location and advances the pointer to the next field.
 *
 * This function will decode a variable of the ASN.1 INTEGER type. In this
 * case, the integer is assumed to be of a larger size than can fit in a C or
 * C++ long type (normally 32 or 64 bits). For example, parameters used to
 * calculate security values are typically larger than these sizes. These
 * variables are stored in character string constant variables. They are
 * represented as decimal strings starting with no prefix. If it is necessary
 * to convert a decimal string to another radix, then use ::rtBigIntSetStr /
 * ::rtBigIntToString functions.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @param object_p     Pointer to a character pointer variable to receive the
 *                       decoded unsigned value. Dynamic memory is allocated
 *                       for the variable using the rtMemAlloc function. The
 *                       decoded variable is represented as a decimal string
 *                       starting with no prefix.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_bigint (ASN1CTXT *ctxt_p, ASN1ConstCharPtr* object_p, 
                         ASN1TagType tagging, int length);

/**
 * This function decodes a variable of the ASN.1 BIT STRING type into a static
 * memory structure. This function call is generated by ASN1C to decode a sized
 * bit string production.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       The length, in OCTETs, of the contents field to be
 *                       decoded. This parameter only has meaning if the
 *                       tagging parameter specifies implicit decoding. If
 *                       explicit, the length is obtained from the decoded
 *                       length field.
 * @param numbits_p    Pointer to an integer variable containing the size (in
 *                       bits) of the sized ASN.1 bit string. An error will
 *                       occur if the number of bits in the decoded string is
 *                       larger than this value. Note that this is also used as
 *                       an output variable - the actual number of decoded bits
 *                       will be returned in this variable.
 * @param object_p     Pointer to a variable to receive the decoded bit string.
 *                       This is assumed to be a static array large enough to
 *                       hold the number of bits specified in the *numbits_p
 *                       input parameter.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_bitstr_s (ASN1CTXT *ctxt_p, ASN1OCTET* object_p, 
                           ASN1UINT* numbits_p, ASN1TagType tagging, 
			   int length);

/**
 * This function decodes a variable of the ASN.1 BIT STRING. This function will
 * allocate dynamic memory to store the decoded result.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       The length, in OCTETs, of the contents field to be
 *                       decoded. This parameter only has meaning if the
 *                       tagging parameter specifies implicit decoding. If
 *                       explicit, the length is obtained from the decoded
 *                       length field.
 * @param numbits_p    Pointer to an integer value to receive the decoded
 *                       number of bits.
 * @param object_p2    Pointer to a pointer variable to receive the decoded bit
 *                       string. Dynamic memory is allocated to hold the
 *                       string.Pointer to a variable to receive the decoded
 *                       bit string.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_bitstr (ASN1CTXT *ctxt_p, ASN1ConstOctetPtr* object_p2, 
                         ASN1UINT* numbits_p, ASN1TagType tagging, int length);

/**
 * This function decodes the octet string at the current message pointer
 * location and returns its value. The value is returned in the buffer pointed
 * to by the given character buffer pointer. This is a static buffer that must
 * be large enough to hold the decoded data.
 *
 * @param ctxt_p       Pointer to ASN.1 context block structure
 * @param object_p     Pointer to static octet array to receive decoded data
 * @param numocts_p    Pointer to an integer variable to receive the length of
 *                       the decoded octet string. On input, this parameter is
 *                       used to specify the size of the octet array.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_octstr_s (ASN1CTXT *ctxt_p, ASN1OCTET* object_p, 
                           ASN1UINT* numocts_p, ASN1TagType tagging, 
			   int length);

/**
 * This function decodes the octet string at the current message pointer
 * location and returns its value. This version of the function allocates
 * memory for the decoded string and returns a pointer to the data.
 *
 * @param ctxt_p       Pointer to ASN.1 context block structure
 * @param object_p2    Pointer to a pointer to receive the address of the
 *                       allocated memory into which the decoded data will be
 *                       stored.
 * @param numocts_p    Pointer to an integer variable to receive length of the
 *                       decoded octet string.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_octstr (ASN1CTXT *ctxt_p, ASN1ConstOctetPtr* object_p2, 
                         ASN1UINT* numocts_p, ASN1TagType tagging, int length);

/**
 * This function is the base function for decoding any of the 8-bit character
 * string useful types such as IA5String, VisibleString, etc. This function
 * allocates memory for the decoded string and returns a pointer to the data.
 *
 * @param ctxt_p       Pointer to ASN.1 context block structure
 * @param object_p     Pointer to a pointer to receive the address of the
 *                       allocated memory into which the decoded character
 *                       string data will be stored. The string is assumed to
 *                       be a normal C string containing non-null characters. A
 *                       null terminator is automatically added to the end of
 *                       the string by this function.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param tag          Tag variable to match
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_charstr (ASN1CTXT* ctxt_p, ASN1ConstCharPtr* object_p, 
                          ASN1TagType tagging, ASN1TAG tag, int length);

/**
 * This function is the base function for decoding a 16-bit character string
 * useful type. In the current version of ASN.1, the only string type based on
 * 16-bit Unicode characters is the BMPString type. This function allocates
 * memory for the decoded string and returns a pointer to the data.
 *
 * @param ctxt_p       Pointer to ASN.1 context block structure
 * @param object_p     Pointer to a pointer to receive the address of the
 *                       allocated memory into which the decoded character
 *                       string data will be stored. The string is assumed to
 *                       contain all non-null 16-bit unicode characters. A null
 *                       terminator is automatically added to the end of the
 *                       string by this function.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param tag          Tag variable to match
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_16BitCharStr (ASN1CTXT* ctxt_p, Asn116BitCharString* object_p,
                               ASN1TagType tagging, ASN1TAG tag, int length);

/**
 * This function is the base function for decoding a 32-bit character string
 * useful type. In the current version of ASN.1, the only string type based on
 * 32-bit characters is the UniversalString type. This function allocates
 * memory for the decoded string and returns a pointer to the data.
 *
 * @param ctxt_p       Pointer to ASN.1 context block structure
 * @param object_p     Pointer to a pointer to receive the address of the
 *                       allocated memory into which the decoded character
 *                       string data will be stored. The string is assumed to
 *                       contain all non-null 32-bit unicode characters. A null
 *                       terminator is automatically added to the end of the
 *                       string by this function.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param tag          Tag variable to match.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_32BitCharStr (ASN1CTXT* ctxt_p, Asn132BitCharString* object_p,
                               ASN1TagType tagging, ASN1TAG tag, int length);

/**
 * This function decoded the ASN.1 NULL placeholder type. The null data type
 * contains no data; however, if explicit tagging is specified, it will contain
 * a universal tag value (5) and zero length. This function will parse those
 * values.
 *
 * @param ctxt_p       Pointer to ASN.1 context block structure
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged. The function will do nothing if implicit
 *                       tagging is specified.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_null (ASN1CTXT *ctxt_p, ASN1TagType tagging);

/**
 * This function decodes a value of the ASN.1 object identifier type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param object_p     Pointer to value to receive decoded result. The
 *                       ASN1OBJID structure contains an integer to hold the
 *                       number of subidentifiers and an array to hold the
 *                       subidentifier values.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_objid (ASN1CTXT *ctxt_p, ASN1OBJID *object_p, 
                        ASN1TagType tagging, int length);

/**
 * This function decodes a value of the ASN.1 object identifier type using
 * 64-bit subidentifiers.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param object_p     Pointer to value to receive decoded result. The
 *                       ASN1OID64 structure contains an integer to hold the
 *                       number of subidentifiers and an array of 64-bit
 *                       unsigned integers to hold the subidentifier values.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_oid64 (ASN1CTXT *ctxt_p, ASN1OID64 *object_p, 
                        ASN1TagType tagging, int length);

/**
 * This function decodes a value of the ASN.1 RELATIVE-OID type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param object_p     Pointer to value to receive decoded result. The
 *                       ASN1OBJID structure contains an integer to hold the
 *                       number of subidentifiers and an array to hold the
 *                       subidentifier values.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_reloid (ASN1CTXT *ctxt_p, ASN1OBJID *object_p, 
                         ASN1TagType tagging, int length);

/**
 * This function decodes a value of the ASN.1 REAL type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param object_p     Pointer to value to receive decoded result. The ASN1REAL
 *                       data type is a double-precision floating point number
 *                       type (C double type).
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_real (ASN1CTXT *ctxt_p, ASN1REAL *object_p, 
                       ASN1TagType tagging, int length);

/**
 * This function decodes a value of the ASN.1 ENUMERATED type. This function is
 * identical to the integer decode function (xd_integer) except that the
 * enumerated universal tag value is validated.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param object_p     Pointer to value to receive decoded result.
 * @param tagging      Specifies whether element is implicitly or explicitly
 *                       tagged.
 * @param length       Length of data to retrieve. Valid for implicit case
 *                       only.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_enum (ASN1CTXT *ctxt_p, ASN1ENUM *object_p, 
                       ASN1TagType tagging, int length);

/**
 * This function decodes a value of an ASN.1 open type. An open type is used to
 * model the old ASN.1 ANY and ANY DEFINED BY types. It is also used to model
 * variable type references within information objects (for example,
 * TYPE-IDENTIFER.&Type). Dynamic memory is allocated to hold the decoded
 * result.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param object_p2    Pointer to value to receive decoded result.
 * @param numocts_p    Pointer to an integer variable to receive length of the
 *                       decoded octet string.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_OpenType (ASN1CTXT *ctxt_p, ASN1ConstOctetPtr* object_p2, 
                           ASN1UINT* numocts_p);

/**
 * This function decodes an ASN.1 open type extension. This is the optional
 * data that follows the ... in multi-version messages. Dynamic memory is
 * allocated to hold the decoded result.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param ccb_p        Pointer to a 'context control block' structure. This is
 *                       basically a loop control mechanism to keep the
 *                       variable associated with parsing a nested constructed
 *                       element straight.
 * @param tag          Next expected tag value (or ASN_K_NOTAG value if last
 *                       field). The routine will loop through elements until
 *                       matching tag found or some other error occurs.
 * @param pElemList    The pointer to linked list structure. The list will
 *                       contain elements of ASN1OpenType type.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_OpenTypeExt (ASN1CTXT* ctxt_p, ASN1CCB* ccb_p, ASN1TAG tag, 
                              Asn1RTDList *pElemList);

/**
 * This function appends a decoded open type element onto a list of elements.
 * It is used by the ASN1C compiler to decode messages with multiple extension
 * fields following an extension marker (...).
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param pElemList    Pointer to element list onto which the decoded element
 *                       should be appended.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_OpenTypeAppend (ASN1CTXT *ctxt_p, Asn1RTDList *pElemList);

/**
 * This function sets the decode pointer (cursor) to point at the beginning of
 * the encoded ASN.1 message that is to be decoded. This function must be
 * called prior to calling any of the other decode functions.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param msg_p        Pointer to message buffer containing data to be decoded.
 * @param msglen       Pointer to size of the message data buffer. This is an
 *                       optional parameter. It is used to verify that the
 *                       length of the data encoded in the message is less than
 *                       or equal to the given size of the message buffer. If
 *                       the message size is unknown at the time of decoding,
 *                       this argument can be set to zero and the size check
 *                       will be bypassed.
 * @param tag_p        Pointer to an ASN.1 tag variable to recieve the value of
 *                       the initial tag parsed from a message. This is an
 *                       optional parameter. It can be set to NULL is the user
 *                       does not require the initial tag value.
 * @param len_p        Pointer to an integer variable to receive the decoded
 *                       message length. Note that this is the total length of
 *                       the message from the start of message, NOT the actual
 *                       length decoded after the initial tag. In other words
 *                       the length of the initial tag and length are added on
 *                       to the parsed length. This is an optional parameter.
 *                       It can be set to NULL if the user does not require the
 *                       message length value.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_setp (ASN1CTXT *ctxt_p, ASN1ConstOctetPtr msg_p, 
                       int msglen, ASN1TAG *tag_p, int *len_p);

/**
 * This function calculates the actual length of an indefinite length message
 * component.
 *
 * @param msg_p        Pointer to an indefinite length message component.
 * @param bufSize      Size of the message's buffer
 */
EXTERNBER int xd_indeflen_ex (ASN1ConstOctetPtr msg_p, int bufSize);

/* Backward compatibility macro */
#define xd_indeflen(m) xd_indeflen_ex(m, INT_MAX)

/**
 * This function decodes an ASN.1 length value.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param len_p        Pointer to integer variable to receive the the decoded
 *                       length value. If the length is indefinite, the
 *                       constant ASN_K_INDEFLEN is returned.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_len (ASN1CTXT *ctxt_p, int *len_p);

/**
 * This function checks for the end of a constructed element. It is typically
 * used by the ASN1C compiler to set up a loop for decoding a constructed type
 * such as a SEQUENCE or SET.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param ccb_p        Pointer to a context control block (ccb). This is a
 *                       structure added to compiler generated code to keep
 *                       track of the current position within nested
 *                       structures.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_chkend (ASN1CTXT *ctxt_p, ASN1CCB* ccb_p);

/**
 * This function determines the count of elements within a constructed type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param length       Length of the constructed type.
 * @param count_p      Pointer to an integer variable to receive the element
 *                       count.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_count (ASN1CTXT *ctxt_p, int length, int *count_p);

/**
 * This function skips to the next element in the decode buffer.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_NextElement (ASN1CTXT* ctxt_p);

/**
 * This function is an optimized version of the xd_tag_len function. If the
 * ASN1C compiler determines the tag at a given location to be parsed is only
 * one byte long (a typical case) then it will use this function. It reads a
 * single tag byte and then immediately parses the length field.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param len_p        Length of message component. Returned as follows: >= 0
 *                       component is fixed length ASN_K_INDEFLEN component is
 *                       indefinite length
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_Tag1AndLen (ASN1CTXT* ctxt_p, ASN1INT* len_p);

/* internal decode function to do memory copies */
/**
 * This function copies data from the contents field of a message component
 * into the target object.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param             *object_p A pointer to a memory structure to receive the
 *                       copied data.
 * @param length       The number of bytes to copy from the contents field.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_memcpy (ASN1CTXT* ctxt_p, ASN1OCTET *object_p, int length) ;

/**
 * The xd_match1 function does a comparison between the given tag and the tag
 * at the current decode pointer position to determine if they match. It then
 * returns the result of the match operation. In contrast to ::xd_match
 * function xd_match1 is an optimized version and can be used only to compare
 * primitive tags (with number less than 31). It is always advance the decode
 * pointer to the contents field if matching is successful. Note, that the tag
 * should be specified as an octet, like it is used in BER encoding.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tag          Tag variable to match in octet format.
 * @param len_p        Length of message component. Returned as follows: >= 0
 *                       component is fixed length ASN_K_INDEFLEN component is
 *                       indefinite length
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xd_match1 (ASN1CTXT *ctxt_p, ASN1OCTET tag, int *len_p);


/** @} berdecruntime */

/* file decode functions */

/** @defgroup berderfilefun BER/DER C File Functions.
 * @{
 *
 * The BER/DER file decode functions allow decode operations to be performed
 * directly on encoded entities within a binary file as opposed to in memory.
 * This makes it possible to parse tag and length variables to determine when
 * pieces of a message can be read into memory. The "tap3batch" sample program
 * provides a good illustration of how these functions are used. They can be
 * applied to a TAP3 batch file to get at the call-detail records for
 * sequential processing without having to read the entire file into memory.
 *
 * These functions all begin with the prefix "xdf_" to distinguish them from
 * the other decode functions. The following is a description of the various
 * functions that make up this package.
 */

#ifndef _KERNEL
/**
 * This function decodes ASN.1 tag from a file stream into a standard 32-bit
 * ASN.1 tag structure.
 *
 * @param fp           The file pointer of the binary file to be decoded. It is
 *                       expected that the current file position is at the
 *                       first byte of the tag to be decoded.
 * @param ptag         A pointer to an ASN.1 tag structure to receive the
 *                       decoded tag.
 * @param buffer       The buffer to receive the parsed data.
 * @param pbufidx      The pointer to the current buffer index containing
 *                       offset to the location where the decoded bytes should
 *                       be copied in the output buffer. The updated buffer
 *                       index set to point at the first free byte after the
 *                       tag is parsed and copied into the buffer.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xdf_tag (FILE* fp, ASN1TAG* ptag, ASN1OCTET* buffer, int* pbufidx);

/**
 * This function decodes the ASN.1 length from a file stream.
 *
 * @param fp           The file pointer of the binary file to be decoded. It is
 *                       expected that the current file position is at the
 *                       first byte of the tag to be decoded.
 * @param plen         A pointer to an integer to receive the decoded length
 *                       value.
 * @param buffer       The buffer to receive the parsed data.
 * @param pbufidx      The pointer to the current buffer index containing
 *                       offset to the location where the decoded bytes should
 *                       be copied in the output buffer. The updated buffer
 *                       index set to point at the first free byte after the
 *                       tag is parsed and copied into the buffer.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xdf_len (FILE* fp, ASN1INT* plen, ASN1OCTET* buffer, int* pbufidx);

/**
 * This function decodes an ASN.1 tag and length pair from a file stream.
 *
 * @param fp           The file pointer of the binary file to be decoded. It is
 *                       expected that the current file position is at the
 *                       first byte of the tag to be decoded.
 * @param ptag         A pointer to an ASN1TAG variable to receive parsed the
 *                       tag value.
 * @param plen         A pointer to an integer to receive the decoded length
 *                       value.
 * @param buffer       The buffer to receive the parsed data.
 * @param pbufidx      The pointer to the current buffer index containing
 *                       offset to the location where the decoded bytes should
 *                       be copied in the output buffer. The updated buffer
 *                       index set to point at the first free byte after the
 *                       tag is parsed and copied into the buffer.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xdf_TagAndLen (FILE* fp, ASN1TAG* ptag, ASN1INT* plen, 
                             ASN1OCTET* buffer, int* pbufidx);

/**
 * This function consumes bytes from the file stream until a matching
 * end-of-context (EOC) maker is found. The bytes read from the file are stored
 * in the given buffer for later processing. An indefinite marker is assumed to
 * have been parsed prior to calling this function.
 *
 * @param fp           A file pointer of a binary file to be decoded. It is
 *                       expected that the current file position is the first
 *                       byte following an indefinite length marker (0x80
 *                       byte).
 * @param buffer       The buffer to receive the parsed data.
 * @param bufsiz       The size of the buffer to receive the parsed data.
 * @param pbufidx      The pointer to the current buffer index containing
 *                       offset to the location where the decoded bytes should
 *                       be copied in the output buffer. The updated buffer
 *                       index set to point at the first free byte index after
 *                       the parsed data is copied to the buffer.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xdf_ReadPastEOC (FILE* fp, ASN1OCTET* buffer, 
                               int bufsiz, int* pbufidx);

/** 
 * This routine reads the contents of a BER tag-length-value (TLV) into the
 * given buffer. The TLV can be of indefinite length.
 *
 * @param fp           A file pointer of a binary file to be decoded. It is
 *                       expected that the current file position is the first
 *                       byte following an indefinite length marker (0x80
 *                       byte).
 * @param len          The length of data to be read from the file. This can be
 *                       the indefinite constant (ASN_K_INDEFLEN) indicating
 *                       all data up to the corresponding end-of-context (EOC)
 *                       marker should be read.
 * @param buffer       The buffer to receive the parsed data.
 * @param bufsiz       The size of the buffer to receive the parsed data.
 * @param pbufidx      The pointer to the current buffer index containing
 *                       offset to the location where the decoded bytes should
 *                       be copied in the output buffer. The updated buffer
 *                       index set to point at the first free byte index after
 *                       the parsed data is copied to the buffer.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xdf_ReadContents (FILE* fp, int len, ASN1OCTET* buffer,
                                int bufsiz, int* pbufidx);
#endif  /* _KERNEL */
/** @} berderfilefun*/ 



/* encode functions */
/** @defgroup berencruntime BER/DER C Encode Functions.
 * @{
 *
 * BER/DER C encode functions handle the BER encoding of the primitive ASN.1
 * data types and ASN.1 length and tag fields within a message. Calls to these
 * functions are assembled in the C source code generated by the ASN1C complier
 * to accomplish the encoding of complex ASN.1 structures. These functions are
 * also directly callable from within a user's application program if the need
 * to accomplish a low level encoding function exists.
 *
 * The procedure to call the encode function that encodes a primitive type is
 * the same as the procedure to call a compiler generated encode function
 * described above. The rtInitContext and xe_setp functions must first be
 * called to initialize a context variable and set a pointer to the buffer into
 * which the variable is to be encoded. A static encode buffer is specified by
 * specifying a pointer to a buffer and buffer size. Setting the buffer address
 * to NULL and buffer size to 0 specifies a dynamic buffer. The primitive
 * encode function is invoked. Finally, xe_getp is called to retrieve a pointer to
 * the encoded message compound.
 */

/**
 * This function is used to encode ASN.1 tag and length fields that preface
 * each block of message data. The ANS1C complier generates calls to this
 * function to handle teh encoding of user-defined tags within an ASN.1
 * specification. The function is also called from within the runtime library
 * functions to handle the addition of the universal tags defined for each of
 * the ASN.1 primitive data types.
 *
 * @param             *ctxt_p A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param tag          The ASN.1 tag to be encoded in the message. This
 *                       parameter is passed using the ASN1C internal tag
 *                       representation. It is passed as an unsigned 32-bit
 *                       integer.
 * @param length       The length of the contents field previously encoded.
 *                       This parameter can be used to specify the actual
 *                       length, or the special constant ASN_K_INDEFLEN can be
 *                       used to specify that an indefinite length
 *                       specification should be encoded.
 * @return             Length of the encoded message component. This is equal
 *                       to the given length plus the additional bytes that are
 *                       added for the tag and length fields. A negative status
 *                       will be returned if the encoding is not successful.
 */
EXTERNBER int xe_tag_len (ASN1CTXT *ctxt_p, ASN1TAG tag, int length) ;

/**
 * This function will encode a variable of the ASN.1 BOOLEAN type.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param             *object_p A pointer to the BOOLEAN value to be encoded
 *                       (note that pointer to the BOOLEAN is passed, not the
 *                       BOOLEAN itself. This may seem awkward, but to keep the
 *                       calling sequence of all encode functions the same,
 *                       pointers were used in all cases). A BOOLEAN is defined
 *                       as a single OCTET whose value is 0 for FALSE and any
 *                       other value for TRUE.
 * @param tagging      An enumerated type whose value is set to either ASN1EXPL
 *                       (for explicit tagging) or ASN1IMPL (for implicit).
 *                       Controls whether the universal tag value for this type
 *                       is added or not. Users will generally always set this
 *                       value to ASN1EXPL.
 * @return             The length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_boolean (ASN1CTXT* ctxt_p, ASN1BOOL *object_p, 
                          ASN1TagType tagging);

/**
 * This function encodes a variable of the ASN.1 INTEGER type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to the INTEGER value to be encoded (note that
 *                       a pointer to the INTEGER is passed, not the INTEGER
 *                       value itself. This may seem awkward, but to keep the
 *                       calling sequence of all encode functions the same,
 *                       pointers were used in all cases). The ASN1INT type is
 *                       set to the C type 'int' in the asn1type.h file. This
 *                       is assumed to represent a 32-bit integer value.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_integer (ASN1CTXT* ctxt_p, int *object_p, ASN1TagType tagging);

/**
 * This function encodes an unsigned variable of the ASN.1 INTEGER type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to the unsigned INTEGER value to be encoded
 *                       (note that a pointer to the unsigned INTEGER is
 *                       passed, not the INTEGER value itself. This may seem
 *                       awkward, but to keep the calling sequence of all
 *                       encode functions the same, pointers were used in all
 *                       cases). The ASN1UINT type is set to the C type
 *                       'unsigned int' in the asn1type.h file. This is assumed
 *                       to represent a 32-bit integer value.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_unsigned (ASN1CTXT* ctxt_p, ASN1UINT *object_p, 
                           ASN1TagType tagging);

/**
 * This function encodes an 8-bit variable of the ASN.1 INTEGER type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to the 8-bit INTEGER value to be encoded (note
 *                       that a pointer is passed, not the INTEGER value
 *                       itself. This may seem awkward, but to keep the calling
 *                       sequence of all encode functions the same, pointers
 *                       were used in all cases). The ASN1INT8 type is set to
 *                       the C type 'signed char' in the asn1type.h file. This
 *                       is assumed to represent an 8-bit integer value.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_int8 (ASN1CTXT* ctxt_p, ASN1INT8 *object_p, ASN1TagType tagging);

/**
 * This function encodes a 16-bit variable of the ASN.1 INTEGER type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to the 16-bit INTEGER value to be encoded
 *                       (note that a pointer is passed, not the INTEGER value
 *                       itself. This may seem awkward, but to keep the calling
 *                       sequence of all encode functions the same, pointers
 *                       were used in all cases). The ASN1SINT type is set to
 *                       the C type 'short' in the asn1type.h file. This is
 *                       assumed to represent a 16-bit integer value.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_int16 (ASN1CTXT* ctxt_p, ASN1SINT *object_p, ASN1TagType tagging);

/**
 * This function encodes a 64-bit variable of the ASN.1 INTEGER type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to the 64-bit INTEGER value to be encoded
 *                       (note that a pointer to the INTEGER is passed, not the
 *                       INTEGER value itself. This may seem awkward, but to
 *                       keep the calling sequence of all encode functions the
 *                       same, pointers were used in all cases). The ASN1INT64
 *                       type is set to the C type '__int64', 'long long' or
 *                       'long' in the asn1type.h file (depends on the used
 *                       platform and the compiler). This is assumed to
 *                       represent a 64-bit integer value.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_int64 (ASN1CTXT* ctxt_p, ASN1INT64 *object_p, 
                        ASN1TagType tagging);

/**
 * This function encodes an unsigned 64-bit variable of the ASN.1 INTEGER type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to the unsigned 64-bit INTEGER value to be
 *                       encoded (note that a pointer to the unsigned INTEGER
 *                       is passed, not the INTEGER value itself. This may seem
 *                       awkward, but to keep the calling sequence of all
 *                       encode functions the same, pointers were used in all
 *                       cases). The ASN1UINT64 type is set to the C type
 *                       'unsigned __int64', 'unsigned long long' or 'unsigned
 *                       long' in the asn1type.h file (depends on the used
 *                       platform and the compiler). This is assumed to
 *                       represent a 64-bit integer value.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_uint64 (ASN1CTXT* ctxt_p, ASN1UINT64 *object_p, 
                         ASN1TagType tagging);

/**
 * This function encodes an unsigned 8-bit variable of the ASN.1 INTEGER type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to the unsigned 8-bit INTEGER value to be
 *                       encoded (note that a pointer is passed, not the
 *                       INTEGER value itself. This may seem awkward, but to
 *                       keep the calling sequence of all encode functions the
 *                       same, pointers were used in all cases). The ASN1OCTET
 *                       type is set to the C type 'unsigned char' in the
 *                       asn1type.h file. This is assumed to represent an 8-bit
 *                       integer value.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_uint8 (ASN1CTXT* ctxt_p, ASN1UINT8 *object_p, ASN1TagType tagging);

/**
 * This function encodes an unsigned 16-bit variable of the ASN.1 INTEGER type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to the unsigned 16-bit INTEGER value to be
 *                       encoded (note that a pointer is passed, not the
 *                       INTEGER value itself. This may seem awkward, but to
 *                       keep the calling sequence of all encode functions the
 *                       same, pointers were used in all cases). The ASN1USINT
 *                       type is set to the C type 'unsigned short' in the
 *                       asn1type.h file. This is assumed to represent a 16-bit
 *                       integer value.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_uint16 (ASN1CTXT* ctxt_p, ASN1USINT *object_p, ASN1TagType tagging);

/**
 * This function encodes a variable of the ASN.1 INTEGER type. In this case,
 * the integer is assumed to be of a larger size than can fit in a C or C++
 * long type (normally 32 or 64 bits). For example, parameters used to
 * calculate security values are typically larger than these sizes.
 *
 * Items of this type are stored in character string constant variables. They
 * can be represented as decimal strings (with no prefixes), as hexadecimal
 * strings starting with a "0x" prefix, as octal strings starting with a "0o"
 * prefix or as binary strings starting with a "0b" prefix. Other radixes
 * currently are not supported. It is highly recommended to use the hexadecimal
 * or binary strings for better performance.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to a character string containing the value to
 *                       be encoded.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_bigint (ASN1CTXT* ctxt_p, ASN1ConstCharPtr object_p, 
                         ASN1TagType tagging);

 /**
 * Unsigned version of xe_bigint function
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     A pointer to a character string containing the value to
 *                       be encoded.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_biguint(ASN1CTXT* ctxt_p, ASN1ConstCharPtr object_p,
                         ASN1TagType tagging);

/**
 * This function will encode a variable of the ASN.1 BIT STRING type.
 *
 * @param ctxt_p       Pointer to a context block structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param object_p     A pointer to an OCTET string containing the bit data to
 *                       be encoded. The string contains bytes having the
 *                       actual bit settings as they are to be encoded in the
 *                       message.
 * @param numbits      The number of bits within the bit string to be encoded.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_bitstr (ASN1CTXT* ctxt_p, ASN1ConstOctetPtr object_p, 
                         ASN1UINT numbits, ASN1TagType tagging);

/**
 * This function will encode a variable of the ASN.1 OCTET STRING type.
 *
 * @param ctxt_p       Pointer to a context block structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param object_p     A pointer to an OCTET string containing the bit data to
 *                       be encoded. The string contains bytes having the
 *                       actual bit settings as they are to be encoded in the
 *                       message.
 * @param numocts      The number of octets (bytes) within the OCTET STRING to
 *                       be encoded.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_octstr (ASN1CTXT* ctxt_p, ASN1ConstOctetPtr object_p, 
                         ASN1UINT numocts, ASN1TagType tagging);

/**
 * This function will encode a variable one of the ASN.1 character string types
 * that are based 8-bit character sets. This includes IA5String, VisibleString,
 * PrintableString, and NumericString
 *
 * @param ctxt_p       Pointer to a context block structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param object_p     A pointer to a null-terminated C character string to be
 *                       encoded
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param tag          The Universal ASN.1 tag to be encoded in the message.
 *                       This parameter is passed using the internal
 *                       representation discussed in Section 4.1.2. It is
 *                       passed as an unsigned 16-bit integer. The tag value
 *                       must represent one of the 8-bit character string types
 *                       documented in the X.680 standard.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_charstr (ASN1CTXT* ctxt_p, ASN1ConstCharPtr object_p, 
                          ASN1TagType tagging, ASN1TAG tag);
 
/**
 * This function will encode a variable one of the ASN.1 character string types
 * that are based on a 16-bit character set. This includes the BMPString type.
 *
 * @param ctxt_p       Pointer to a context block structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param object_p     A pointer t a structure representing a 16-bit character
 *                       string to be encoded. This structure contains a
 *                       character count element and a pointer to an array of
 *                       16-bit character elements represented as 16-bit short
 *                       integers.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param tag          The Universal ASN.1 tag to be encoded in the message.
 *                       This parameter is passed using the internal
 *                       representation discussed in Section 4.1.2. It is
 *                       passed as an unsigned 16-bit integer. The tag value
 *                       must represent one of the 16-bit character string
 *                       types documented in the X.680 standard.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_16BitCharStr (ASN1CTXT* ctxt_p, Asn116BitCharString* object_p, 
                               ASN1TagType tagging, ASN1TAG tag);

/**
 * This function will encode a variable one of the ASN.1 character string types
 * that are based on a 32-bit character set. This includes the UniversalString
 * type.
 *
 * @param ctxt_p       Pointer to a context block structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param object_p     A pointer t a structure representing a 32-bit character
 *                       string to be encoded. This structure contains a
 *                       character count element and a pointer to an array of
 *                       32-bit character elements represented as 16-bit short
 *                       integers.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param tag          The Universal ASN.1 tag to be encoded in the message.
 *                       This parameter is passed using the internal
 *                       representation discussed in Section 4.1.2. It is
 *                       passed as an unsigned 32-bit integer. The tag value
 *                       must represent one of the 32-bit character string
 *                       types documented in the X.680 standard.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_32BitCharStr (ASN1CTXT* ctxt_p, Asn132BitCharString* object_p, 
                               ASN1TagType tagging, ASN1TAG tag);

/**
 * This function will encode an ASN.1 NULL placeholder.
 *
 * @param ctxt_p       Pointer to a context block structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @return             Length of the encoded message component. A negative
 *                       status value will be returned if encoding is not
 *                       successful.
 */
EXTERNBER int xe_null (ASN1CTXT* ctxt_p, ASN1TagType tagging);

/**
 * This function encodes a value of the ASN.1 object identifier type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     Pointer to value to be encoded. The ASN1OBJID structure
 *                       contains a numids fields to hold the number of
 *                       subidentifiers and an array to hold the subidentifier
 *                       values.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_objid (ASN1CTXT* ctxt_p, ASN1OBJID *object_p, 
                        ASN1TagType tagging);

/**
 * This function encodes a value of the ASN.1 object identifier type, using
 * 64-bit subidentifiers.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     Pointer to value to be encoded. The ASN1OID64 structure
 *                       contains a numids fields to hold the number of
 *                       subidentifiers and an array of unsigned 64-bit
 *                       integers to hold the subidentifier values.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_oid64 (ASN1CTXT* ctxt_p, ASN1OID64 *object_p, 
                        ASN1TagType tagging);

/**
 * This function encodes a value of the ASN.1 RELATIVE-OID type.
 *
 * @param ctxt_p       Pointer to context block structure.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @param object_p     Pointer to value to be encoded. The ASN1OBJID structure
 *                       contains a numids fields to hold the number of
 *                       subidentifiers and an array to hold the subidentifier
 *                       values.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_reloid (ASN1CTXT* ctxt_p, ASN1OBJID *object_p, 
                         ASN1TagType tagging);

/**
 * This function encodes a variable of the ASN.1 ENUMERATED type.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store al working variables
 *                       that must be maintained between function calls.
 * @param object_p     A pointer to an integer containing the enumerated value
 *                       to be encoded (Note that a pointer to the value is
 *                       passed not the value itself. This may seem awkward,
 *                       but to keep the calling sequence of all the encode
 *                       function the same, pointers were used in all cases.)
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_enum (ASN1CTXT* ctxt_p, ASN1ENUM *object_p, ASN1TagType tagging);

/**
 * This function will encode a variable of the REAL data type.
 *
 * This function provides support for the plus-infinity and minus-infinity
 * special real values. Use the rtGetPlusInfinity or rtGetMinusInfinity
 * functions to get these special values.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store al working variables
 *                       that must be maintained between function calls.
 * @param             *object_p A pointer to a variable of the ASN1REAL data
 *                       type. This is defined to be the C double type. Special
 *                       real values plus and minus infinity are encoded by
 *                       using the rtGetPlusInfinity and rtGetMinusInfinity
 *                       functions to set the real value to be encoded.
 * @param tagging      An enumerated type whose value is set to either
 *                       'ASN1EXPL' (for explicit tagging) or 'ASN1IMPL' (for
 *                       implicit). Controls whether the universal tag value
 *                       for this type is added or not. Users will generally
 *                       always set this value to 'ASN1EXPL'.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_real (ASN1CTXT* ctxt_p, ASN1REAL *object_p, ASN1TagType tagging);

/**
 * This function will encode a variable of the old (pre- 1994) ASN.1 ANY type
 * or other elements defined in the later standards to be Open Types (for
 * example, a variable type declaration in a CLASS construct as defined in
 * X.681).
 *
 * A variable of this type is considered to be previously encoded ASN.1 message
 * component.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param object_p     A pointer to a buffer containing an encoded ASN.1
 *                       message component.
 * @param numocts      The number of octets to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_OpenType (ASN1CTXT* ctxt_p, ASN1ConstOctetPtr object_p, 
                           ASN1UINT numocts);

/**
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param pElemList    A pointer to open type to be encoded.
 */
EXTERNBER int xe_OpenTypeExt (ASN1CTXT* ctxt_p, Asn1RTDList* pElemList);

/** 
 * This function is used to set the internal buffer within the runtime library
 * encoding context. It must be called after the context variable is
 * initialized by the rtInitContext function and before any other compiler
 * generated or runtime library encode function.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param             *buf_p A pointer to a memory buffer to use to encode a
 *                       message. The buffer should be declared as an array of
 *                       unsigned characters (ASN1OCTETs). This parameter can
 *                       be set to NULL to specify dynamic encoding (i.e., the
 *                       encode functions will dynamically allocate a buffer
 *                       for the message).
 * @param bufsiz       The length of the memory buffer in bytes.
 */
EXTERNBER int xe_setp (ASN1CTXT* ctxt_p, ASN1OCTET *buf_p, int bufsiz);

/** 
 * This function is used to obtain a pointer to the start of an encoded message
 * after calls to the encode function(s) are complete. ANS.1 messages are
 * encoded from the end of a given buffer toward the beginning. Therefore, in
 * practically all cases, the start of the message will not be at the beginning
 * of the buffer.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @return             A pointer to the beginning of the encoded message.
 */
EXTERNBER ASN1OCTET* xe_getp (ASN1CTXT* ctxt_p);

/**
 * This function will free a dynamic encode buffer.
 *
 * The dynamic encode buffer is the buffer that is allocated if dynamic
 * encoding of a message is enabled (passing NULL as the buffer pointer
 * argument to xe_setp enables dynamic encoding.)
 *
 * Note that this is different than the xu_freeall function associated with
 * freeing decoder memory. This function only releases the memory associated
 * with a dynamic encoded buffer. The xu_freeall will not release this memory.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls. The
 *                       dynamic encode buffer pointer is contained within the
 *                       structure.
 */
EXTERNBER void xe_free (ASN1CTXT* ctxt_p);

/**
 * This function will expand a dynamic encode buffer.
 *
 * The dynamic encode buffer is the buffer that is allocated if dynamic
 * encoding of a message is enabled (passing NULL as the buffer pointer
 * argument to xe_setp enables dynamic encoding.)
 *
 * The size of the new buffer is determined by the length argument. If the
 * length is less than a configurable buffer expansion increment size (the
 * constant ASN_K_ENCBUFSIZ), the buffer is expanded by the increment size;
 * otherwise it is expanded by the actual length value.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls. The
 *                       dynamic encode buffer pointer is contained within the
 *                       structure.
 * @param length       The number of bytes required. This may not be size the
 *                       size the buffer is actually expanded by. The buffer
 *                       will be expanded by a fixed-size increment defined by
 *                       ASN_K_ENCBUFSIZ for small requests to limit the
 *                       required number of expansions.
 */
EXTERNBER int xe_expandBuffer (ASN1CTXT *ctxt_p, int length);

/**
 * This function is used to copy bytes into the encode buffer. BER and DER
 * messages are encoded from back-to-front and this function will take this
 * into account when copying bytes. It will also check to ensure that enough
 * space is available in the buffer for the bytes to be copied. If the encode
 * buffer is dynamic, it will be expanded to hold the number of bytes to be
 * copied if not enough space is available. If the buffer is static and enough
 * space is not available, an error (ASN_E_BUFOVFLW) will be returned.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls. The
 *                       dynamic encode buffer pointer is contained within the
 *                       structure.
 * @param object_p     A pointer to a buffer containing the bytes to be copied.
 * @param length       The number of bytes to copy.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_memcpy (ASN1CTXT *ctxt_p, ASN1ConstOctetPtr object_p, 
                         ASN1UINT length) ;

/**
 * This function is used to encode BER or DER length determinant values.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store al working variables
 *                       that must be maintained between function calls.
 * @param length       The length variable to encode. A negative number is
 *                       interpreted that an indefinite length integer should
 *                       be encoded.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_len (ASN1CTXT *ctxt_p, int length) ;

/**
 * This function is added to the generated code for SEQUENCE OF/SET OF
 * constructs to ensure the elements are in the required canonical order for
 * DER.
 *
 * If the elements are not in the right order, they are sorted to be in the
 * correct order prior to encoding.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store al working variables
 *                       that must be maintained between function calls.
 * @param pList        Linked List of message components to be sorted. The
 *                       elements of this list are offsets to encoded
 *                       components within the encode buffer.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_derCanonicalSort (ASN1CTXT* ctxt_p, Asn1RTSList* pList);

/**
 * This function is used to encode a tag value and an indefinite length.
 *
 * This can be used to manually create an indefinite length wrapper around long
 * records.
 *
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store al working variables
 *                       that must be maintained between function calls.
 * @param tag          ASN.1 tag value to be encoded.
 * @param length       The actual length of existing message components.
 * @return             Completion status of operation:
 *                       - 0 (ASN_OK) = success,
 *                       - negative return value is error.
 */
EXTERNBER int xe_TagAndIndefLen (ASN1CTXT *ctxt_p, ASN1TAG tag, int length) ;

/**
 * @param ctxt_p       Pointer to a context structure. This provides a storage
 *                       area for the function to store al working variables
 *                       that must be maintained between function calls.
 * @param length       The actual length of existing message components.
 * @param pDescr       A pointer to a buffer location descriptor.
 */
EXTERNBER void xe_getBufLocDescr (ASN1CTXT *ctxt_p, ASN1UINT length, 
                                  Asn1BufLocDescr* pDescr);
/** @} berencruntime */

/* utility functions */

/** @defgroup berperUtil BER/PER C Utility Functions
 * @{
 *
 * BER/DER utility functions are provided for memory management, formatting
 * output of ASN.1 messages, and error reporting. In many cases, these
 * functions are closely coupled with the rt (runtime) series of common
 * functions. The common functions provide common functionality shared between
 * the BER/DER, PER, and XER runtime libraries. In many cases, these functions
 * simply provide wrappers to the rt functions to maintain compatibility with
 * existing versions of the ASN1C compiler.
 */
EXTERNBER int xu_verify_len (ASN1OCTET *msg_p);
EXTERNBER void *xu_parse_mmbuf (
  ASN1OCTET **buf_p2, int *buflen_p, ASN1OCTET *start_p, int bufsiz);

/**
 * This method provides a front-end to the C malloc function to allocate
 * dynamic memory for decoded message components. The following ASN.1
 * constructs may require allocation of dynamic memory within the generated C
 * structure:
 *   - BIT STRING
 *   - OCTET STRING
 *   - SEQUENCE OF
 *   - SET OF
 *   - ANY
 *
 * This function uses a nibble memory management scheme to make memory
 * allocations more efficient. On an initial allocation request, malloc will be
 * called to obtain a large block of memory. This memory will then be
 * subdivided as subsequent calls to this function are made. When the block is
 * expired, another call to malloc will be made to allocate another large block
 * and then subdivision process repeated. All large memory blocks allocated
 * from within the context are freed when xu_freeall function is called.
 *
 * Note that the main logic for the xu_malloc function is now in the rtMemAlloc
 * function in the common runtime library. This function is still maintained
 * for compatibility purposes, but it acts as a pass through to the rtMemAlloc
 * function.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param nbytes       The number of bytes to allocate.
 * @return             A pointer to the allocated dynamic memory block. This
 *                       will be null if a free block of the requested size
 *                       does not exist.
 */
EXTERNBER void *xu_malloc (ASN1CTXT* ctxt_p, int nbytes);

/**
 * This function will allocate space for a given count of fixed size elements.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 * @param seqOf_p      A pointer to a generic sequence of structure variables
 *                       to receive the returned memory. This structure
 *                       contains a record count and a data pointer element.
 *                       The record count is populated with the recCount passed
 *                       into the function. The data pointer is set to the
 *                       value that is returned from the memory allocation
 *                       function.
 * @param recSize      The number of bytes in one record in the array.
 * @param recCount     The number of records to allocate. A pointer to a
 *                       generic sequence of structure variable to receive the
 *                       returned memory. This structure contains a record
 *                       count and data pointer element. The record count is
 *                       populated with the recCount passed into the function.
 *                       The data pointer is set to the value that is returned
 *                       from the memory allocation function.
 */
EXTERNBER void xu_alloc_array (
  ASN1CTXT* ctxt_p, ASN1SeqOf* seqOf_p, int recSize, int recCount);

/** 
 * This function frees up any dynamic memory allocated by the decode functions
 * in the course of decoding a message. A call to this function releases all
 * memory previously allocated using xu_malloc within the given context.
 *
 * Note that the main logic for the xu_freeall function call is now in the
 * rtMemFree function in the common runtime library. This function is still
 * maintained for compatibility, but it acts as a pass-through to the rtMemFree
 * function.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls.
 */
EXTERNBER void xu_freeall (ASN1CTXT* ctxt_p);


EXTERNBER void xu_octscpy_s (
  ASN1UINT* nocts_p, ASN1OCTET *data_p, char *cstr, char zterm);


EXTERNBER void xu_octscpy_ss (ASN1OctStr *octStr_p, char *cstring, char zterm);


EXTERNBER void xu_octscpy_d (
  ASN1CTXT* ctxt_p, ASN1UINT* nocts_p, ASN1ConstOctetPtr* data_p2, 
  char* cstring, char zterm);


EXTERNBER void xu_octscpy_ds (
  ASN1CTXT* ctxt_p, ASN1DynOctStr *octStr_p, char *cstring, char zterm);


EXTERNBER void xu_octmcpy_s (ASN1OctStr *octStr_p, void* data_p, int datalen);


EXTERNBER void xu_octmcpy_d (
  ASN1CTXT* ctxt_p, ASN1DynOctStr *octStr_p, void* data_p, int datalen);


EXTERNBER char* xu_fetchstr (int numocts, char *data);


EXTERNBER int xu_hexstrcpy (char *data, char *hstring);
EXTERNBER int xu_binstrcpy (char *data, char *bstring);

/**
 * This function dumps an encoded ASN.1 message to the standard output device
 * or to another interface in a formatted display. The display includes, for
 * each message component, message tag (class, form, and ID code) and data (in
 * hexadecimal and character text formats).
 *
 * This function is invoked for each line of text formatted from the given
 * message. The formatted line is passed on the text_p argument. The cbArg_p
 * argument allows a user to defined callback argument to be passed to the
 * callback function. This argument is specified in the call to xu_dump.
 *
 * Use of the callback function is optional. If dump to standard output
 * (stdout) is desired, the argument should be specified as NULL (note: the
 * macro XU_DUMP in asn1type.h can be used for this purpose).
 *
 * @param             *msgptr A pointer to an encoded ASN.1 message.
 * @param cb           Callback function that gets invoked for each line of
 *                       formatted output. For a dump to standard output
 *                       (stdout), this parameter can be specified as NULL.
 * @param cbArg_p      Callback function argument will be passed to the
 *                       callback function.
 * @return             Status of the dump operation. Possible values are ASN_OK
 *                       if decoding is successful or one of the negative
 *                       status codes.
 */
EXTERNBER int xu_dump (ASN1OCTET *msgptr, ASN1DumpCbFunc cb, void* cbArg_p);

#ifndef _KERNEL
/**
 * This function dumps an encoded ASN.1 message to a text file. The display
 * includes, for each message component, message tag (class, form, and ID
 * code), length, and data (in hexadecimal and character text formats).
 *
 * @param             *file_p A text file pointer.
 * @param             *msgptr A pointer to an encoded ASN.1 message buffer.
 * @return             Status of the dump operation. Possible values are ASN_OK
 *                       if decoding is successful or one of the negative
 *                       status codes.
 */
EXTERNBER int xu_fdump (FILE *file_p, ASN1OCTET *msgptr);
#endif /* _KERNEL */

/**
 * This function dumps binary data in raw hexadecimal and character text
 * formats. It can be used only to examine runtime library encode/decode
 * functions input or output data. This function outputs data only to the
 * standard output device.
 *
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C.
 *
 * @param             *data A pointer to the start of the block of memory to be
 *                       dumped.
 * @param numocts      The number of octets (bytes) to be dumped.
 * @param hdrflg       A Boolean variable indicating whether or not a head line
 *                       should be dumped as the first line of the display.
 */
EXTERNBER void xu_hex_dump (ASN1OCTET *data, int numocts, ASN1OCTET hdrflg);


EXTERNBER void xu_fmt_tag (
  ASN1TAG *tag_p, char *class_p, char *form_p, char *id_code);

/**
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C.
 *
 * @param tag_p        Name of the variable.
 * @param bufp         The ASN.1 value.
 */
EXTERNBER char* xu_fmt_tag2 (ASN1TAG* tag_p, char* bufp);


EXTERNBER char* xu_fmt_contents (ASN1CTXT* ctxt_p, int len, int *count);

/**
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during encoding or decoding.
 * @param status       Error status code,
 * @param module       Name of the module (C or C++ source file) in which the
 *                       module occurred.
 * @param lineno       The line at which the error occurred.
 */
#if defined _COMPACT || defined CSP_LITE
#define xu_error(a,b,c,d) TRUE
#else
EXTERNBER int xu_error (ASN1CTXT* ctxt_p, int status, char* module, int lineno);
#endif

/**
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C. Users are
 * encouraged to use the rtMem functions or associated macros for memory
 * management.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during encoding or decoding.
 * @param errprm_p     A pointer to the typed error parameter.
 */ 
#if defined _COMPACT || defined CSP_LITE
#define xu_addErrParm(a,b) TRUE
#else
EXTERNBER int xu_addErrParm (ASN1CTXT* ctxt_p, char* errprm_p);
#endif

/**
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C. Users are
 * encouraged to use the rtMem functions or associated macros for memory
 * management.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during encoding or decoding.
 * @param errParm      The typed error parameter.
 */
#if defined _COMPACT || defined CSP_LITE
#define xu_addIntErrParm(a,b) TRUE
#else
EXTERNBER int xu_addIntErrParm (ASN1CTXT* ctxt_p, int errParm);
#endif


/**
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C. Users are
 * encouraged to use the rtMem functions or associated macros for memory
 * management.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during encoding or decoding.
 * @param errParm      The typed error parameter.
 */
#if defined _COMPACT || defined CSP_LITE
#define xu_addUnsignedErrParm(a,b) TRUE
#else
EXTERNBER int xu_addUnsignedErrParm (ASN1CTXT* ctxt_p, unsigned int errParm);
#endif

/**
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C. Users are
 * encouraged to use the rtMem functions or associated macros for memory
 * management.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during encoding or decoding.
 * @param errParm      The typed error parameter.
 */
#if defined _COMPACT || defined CSP_LITE
#define xu_addTagErrParm(a,b)
#else
EXTERNBER int xu_addTagErrParm (ASN1CTXT* ctxt_p, ASN1TAG errParm);
#endif

/**
 * The function prints information about the last recorded error within the
 * given ASN.1 context structure. The display includes information on the
 * module that generated the error, the source code line number, the status,
 * and a parameterized error message. This function is considered depreciated
 * and is only being maintained to provide backward compatibility with older
 * versions of ASN1C. Users are encouraged to use the rtMem functions or
 * associated macros for memory management.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during encoding or decoding.
 */
#if defined _COMPACT || defined CSP_LITE
#define xu_perror(a)
#else
EXTERNBER void xu_perror (ASN1CTXT* ctxt_p);
#endif

/**
 * This function is identical to xu_perror except it allows the error output to
 * be redirected to another interface (for example, to a syslog-type logging
 * daemon). This is accomplished through the callback function parameter. The
 * prototype for this function is as follows: <code>int callback_function
 * (char* text_p, void* cbArg_p);</code>
 *
 * The text_p parameter contains the formatted error message. The cbArg_p
 * argument allows a user defined callback argument to be passed to the
 * callback function. This argument is specified in the call to xu_log_error.
 *
 * The callback function is invoked twice on a call to xu_log_error. The first
 * call contains the error message text indicating the module, line number, and
 * status of the error. The second call contains the parameterized error
 * message text.
 *
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C. Users are
 * encouraged to use the rtMem functions or associated macros for memory
 * management.
 *
 * @param ctxt_p       The pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during encoding or decoding.
 * @param cb           The callback function that gets invoked for each line of
 *                       formatted error text.
 * @param cbArg_p      The callback function argument.
 */
#if defined _COMPACT || defined CSP_LITE
#define xu_log_error(a,b,c)
#else
EXTERNBER void xu_log_error (ASN1CTXT* ctxt_p, ASN1DumpCbFunc cb, void* cbArg_p);
#endif

/**
 * This function provides parameterized error text corresponding to the last
 * error recorded in the given ASN.1 context structure.
 *
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C. Users are
 * encouraged to use the rtMem functions or associated macros for memory
 * management.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during the encoding or the
 *                       decoding.
 * @param bufp         A pointer to a text buffer in which the parameterized
 *                       error message is to be formatted. The call is
 *                       responsible for allocating space for this message. A
 *                       128-bit buffer should be sufficient for all messages.
 * @return             A pointer to the formatted error message. This is the
 *                       address of the buffer passed as the second input
 *                       argument.
 */
#if defined _COMPACT || defined CSP_LITE
#define xu_fmtErrMsg(a,b) ""
#else
EXTERNBER char* xu_fmtErrMsg (ASN1CTXT* ctxt_p, char* bufp);
#endif


#ifndef _KERNEL
EXTERNBER int xu_fread (FILE* fp, ASN1OCTET* bufp, int bufsiz);
#endif /* _KERNEL */

/**
 * This function is considered depreciated and is only being maintained to
 * provide backward compatibility with older versions of ASN1C.
 *
 * @param ctxt_p       A pointer to a context structure. This provides a
 *                       storage area for the function to store all working
 *                       variables that must be maintained between function
 *                       calls. This structure holds information on the last
 *                       error that occurred during the encoding or the
 *                       decoding.
 * @param list_p       A pointer to a linked list structure onto which the data
 *                       is to be appended.
 * @param data_p       A pointer to the data item to be appended to the list.
 */
EXTERNBER ASN1ListElem* xu_list_append (
  ASN1CTXT* ctxt_p, ASN1ListElem* list_p, void* data_p);


EXTERNBER void xu_SaveBufferState (ASN1CTXT* pCtxt, ASN1BUFSAVE* pSavedInfo);
EXTERNBER void xu_RestoreBufferState (ASN1CTXT* pCtxt, ASN1BUFSAVE* pSavedInfo);
/** @} berperUtil */


/* This macro will fetch the next byte in the input stream.  A test is  */
/* done for buffer overrun.                                             */

#define XD_MEMCPY1(ctxt_p, object_p) \
(((ASN1BUF_INDEFLEN(ctxt_p)) || ((ctxt_p)->buffer.byteIndex < (ctxt_p)->buffer.size)) ? \
(*object_p = *ASN1BUF_PTR(ctxt_p), (ctxt_p)->buffer.byteIndex ++, ASN_OK) : ASN_E_ENDOFBUF)

/* This macro will fetch the next byte in the input stream.  No test is */
/* done for buffer overrun..                                            */

#define XD_FETCH1(ctxt_p) ((ctxt_p)->buffer.data[(ctxt_p)->buffer.byteIndex++])

/* This macro will match a single-byte tag. It does not advance the     */
/* decode cursor.                                                       */

#define XD_PEEKTAG(ctxt_p, tag) \
(((ctxt_p)->buffer.data[(ctxt_p)->buffer.byteIndex] & (~0x20)) == (tag & (~0x20)))

/* This macro will test for an EOC (end-of-context) marker */

#define XD_MATCHEOC(ctxt_p) \
( ( (ctxt_p)->buffer.byteIndex + 2 <= (ctxt_p)->buffer.size ) && \
( (ctxt_p)->buffer.data[(ctxt_p)->buffer.byteIndex] == 0 ) && \
( (ctxt_p)->buffer.data[(ctxt_p)->buffer.byteIndex + 1] == 0 ) )

/* This macro will advance the decode buffer index by the given number  */
/* number of bytes.                                                     */

#define XD_BUMPIDX(ctxt_p, nbytes) ((ctxt_p)->buffer.byteIndex += nbytes)

/* This macro will test for buffer overrun */

#define XD_CHKBUFEND(ctxt_p) \
(((ASN1BUF_INDEFLEN(ctxt_p)) || \
((ctxt_p)->buffer.byteIndex <= (ctxt_p)->buffer.size)) ? ASN_OK : ASN_E_ENDOFBUF)

/* This macro will test if the given length value is within the current */
/* bounds of the message buffer.  The given length value is assumed to  */
/* be a definite length (i.e != ASN_K_INDEFLEN)..                       */

#define XD_CHKDEFLEN(ctxt_p,len) \
(((ASN1BUF_INDEFLEN(ctxt_p)) || \
(((ctxt_p)->buffer.byteIndex + len) <= (ctxt_p)->buffer.size)) ? \
ASN_OK : ASN_E_ENDOFBUF)

/* This macro will test for EOB */

#define XD_CHKEOB(ctxt_p) \
(((ctxt_p)->buffer.byteIndex + 2 > (ctxt_p)->buffer.size) ? TRUE : \
(((ctxt_p)->buffer.data[(ctxt_p)->buffer.byteIndex] == 0 && \
(ctxt_p)->buffer.data[(ctxt_p)->buffer.byteIndex + 1] == 0 ) ? \
TRUE : FALSE))

/* This macro will test for CCB overrun */

#define XD_CHKEND(ctxt_p,ccb_p) \
(((ccb_p)->len == ASN_K_INDEFLEN) ? XD_CHKEOB(ctxt_p) : \
((ASN1BUF_PTR(ctxt_p) - (ccb_p)->ptr >= (ccb_p)->len) || \
((ctxt_p)->buffer.byteIndex >= (ctxt_p)->buffer.size)))

#ifdef __cplusplus
}
#endif
/** @} berruntime */ 
#endif /* _ASN1BER_H_ */
