// Copyright (c) 2001-2009 Objective Systems, Inc. (http://www.obj-sys.com) 
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available 
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Objective Systems, Inc - initial contribution.
//
// Contributors:
//
// Description:
// 

/*
// CHANGE LOG
// Date         Init    Description
// 04/30/02     AB      Added Universal string routines
// 05/08/02     AB      Added p?_oid64 prototypes
// 05/10/02     AB      Added RELATIVE-OID
// 10/15/02     ED      Changes to PER permitted alphabet constraint
//                      handling.
// 10/27/02     AB      Int64/UInt64 encode/decode funcs added
// 11/06/02     AB      PD_BYTE_ALIGN0 added
// 10/31/03     CZ      Expand mainpage text.
//
//
*/
/** 
 * @file rtpersrc/asn1per.h 
 * ASN.1 runtime constants, data structure definitions, and functions to
 * support the Packet Encoding Rules (PER) as defined in the ITU-T X.691
 * standard.
 */

/** 
 * @mainpage ASN1C PER 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 Packed Encoding Rules (PER)as defined in
 * the X.691 ITU-T  standard. These PER specific C++ runtime classes 
 * include the PER message buffer classes.
 *
 * The <B> ASN.1 PER Runtime Library</B> contains 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 items:
 *   <UL> <LI>A global include file ("rtpersrc/asn1per.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.
 */


/**
@file
@internalTechnology
*/

#ifndef _OSRTPER_H_
#define _OSRTPER_H_

#include "rtsrc/asn1type.h"
#include "rtsrc/asn1CharSet.h"

/** @defgroup perruntime PER Runtime Library Functions.
 * @{
 * The ASN.1 Packed Encoding Rules (PER) runtime library contains the  
 * low-level constants, types, and functions that are assembled by the 
 * compiler to encode/decode more complex structures. 
 * The PER low-level C encode/decode functions are identified by their 
 * prefixes: pe_ for PER encode, pd_ for PERdecode, and pu_ for PER 
 * utility functions.
 *  
 */


/* The following constant is stored in an enumerated value if the       */
/* parsed value is not within the defined set of extended enum values   */
/* (note: this is only done in the case of PER because the actual value */
/* is not known - in BER, the actual value is stored)..                 */

#define ASN_K_EXTENUM   999

/* 
*Structure to track encoded PER fields 
*/

typedef struct PERField {
   const char* name;
   size_t       bitOffset;
   size_t       numbits;
} PERField;

/* 
*Structure to track encoded PER fields 
*/
typedef struct {
   unsigned char lb, lbm;
   char fmtBitBuffer[40], fmtHexBuffer[10], fmtAscBuffer[10];
   int  fmtBitCharIdx, fmtHexCharIdx, fmtAscCharIdx;
} BinDumpBuffer;

/* Macro to create a character set */

#define PU_SETCHARSET(csetvar, canset, abits, ubits) \
csetvar.charSet.nchars = 0; \
csetvar.canonicalSet = canset; \
csetvar.canonicalSetSize = sizeof(canset)-1; \
csetvar.canonicalSetBits = pu_bitcnt(csetvar.canonicalSetSize); \
csetvar.charSetUnalignedBits = ubits; \
csetvar.charSetAlignedBits = abits;


/* Macros */

#ifdef _TRACE
#define PU_INSLENFLD(pctxt)       pu_insLenField(pctxt)
#define PU_NEWFIELD(pctxt,suffix) pu_newField(pctxt,suffix)
#define PU_PUSHNAME(pctxt,name)   pu_pushName(pctxt,name)
#define PU_POPNAME(pctxt)         pu_popName(pctxt)
#define PU_SETBITOFFSET(pctxt)    pu_setFldBitOffset(pctxt)
#define PU_SETBITCOUNT(pctxt)     pu_setFldBitCount(pctxt)
#define PU_PUSHELEMNAME(pctxt,idx) pu_pushElemName(pctxt,idx)
#else
#define PU_INSLENFLD(pctxt)
#define PU_NEWFIELD(pctxt,suffix)
#define PU_PUSHNAME(pctxt,name)
#define PU_POPNAME(pctxt)
#define PU_SETBITOFFSET(pctxt)
#define PU_SETBITCOUNT(pctxt)
#define PU_PUSHELEMNAME(pctxt,idx)
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __SYMBIAN32__       /* For Symbian */
#define EXTPERCLASS

#ifdef BUILDASN1PERDLL
#define EXTERNPER       EXPORT_C
#define EXTPERMETHOD   EXPORT_C
#elif defined(USEASN1PERDLL)
#define EXTERNPER       IMPORT_C
#define EXTPERMETHOD   IMPORT_C
#else
#define EXTERNPER
#define EXTPERMETHOD
#endif /* BUILDASN1PERDLL */

#else                      /* Other O/S's */
#define EXTPERMETHOD

#ifdef BUILDASN1PERDLL
#define EXTERNPER       __declspec(dllexport)
#define EXTPERCLASS   __declspec(dllexport)
#elif defined (USEASN1PERDLL)
#define EXTERNPER       __declspec(dllimport)
#define EXTPERCLASS   __declspec(dllimport)
#else
#define EXTERNPER
#define EXTPERCLASS
#endif /* BUILDASN1PERDLL */

#endif

/* Function prototypes */

#define PD_INCRBITIDX(pctxt) \
((--(pctxt)->buffer.bitOffset < 0) ? \
((++(pctxt)->buffer.byteIndex >= (pctxt)->buffer.size) ? RTERR_ENDOFBUF : \
((pctxt)->buffer.bitOffset = 7, 0)) : 0)

/* This macro is an optimized version of pd_bit function */

#define PD_BIT(pctxt,pvalue) \
((PD_INCRBITIDX (pctxt) != 0) ? RTERR_ENDOFBUF : ((pvalue) ? \
((*(pvalue) = (OSOCTET)((((pctxt)->buffer.data[(pctxt)->buffer.byteIndex]) & \
(OSINTCONST(1) << (pctxt)->buffer.bitOffset)) != 0)), 0) : 0 ))

/* This macro is an optimized version of pu_getSizeConstraint function */

#define PU_GETSIZECONSTRAINT(pctxt,extbit,pSize) \
((((pSize) = ACINFO(pctxt)->pSizeConstraint) != 0) ? \
((((pSize) = ACINFO(pctxt)->pSizeConstraint)->extended == extbit)?(pSize) : \
pu_getSizeConstraint (pctxt,extbit)) : NULL)

/* This macro calculates the relative bit offset to the current buffer position. */

#define PU_GETCTXTBITOFFSET(pctxt) \
(((pctxt)->buffer.byteIndex * 8) + (8 - (pctxt)->buffer.bitOffset))

/* This macro sets the bit offset to the given value within the context */

#define PU_SETCTXTBITOFFSET(pctxt,_bitOffset) \
do { \
(pctxt)->buffer.byteIndex = (_bitOffset / 8); \
(pctxt)->buffer.bitOffset = (OSUINT16)(8 - (_bitOffset % 8)); \
} while(0)

/* These macros are an optimized version of pd_byte_align function */

#define PD_BYTE_ALIGN0(pctxt) \
((!(pctxt)->buffer.aligned) ? 0 : \
(((pctxt)->buffer.bitOffset != 8) ? ( \
(pctxt)->buffer.byteIndex++,       \
(pctxt)->buffer.bitOffset = 8,     \
0) : 0                    \
))

#ifdef _TRACE
#define PD_BYTE_ALIGN(pctxt) \
((!(pctxt)->buffer.aligned) ? 0 : \
(((pctxt)->buffer.bitOffset != 8) ? ( \
(pctxt)->buffer.byteIndex++,       \
(pctxt)->buffer.bitOffset = 8,     \
pu_setFldBitOffset(pctxt),         \
0) : 0                    \
))
#else
#define PD_BYTE_ALIGN PD_BYTE_ALIGN0
#endif

#define PD_CHECKSEQOFLEN(pctxt,numElements,minElemBits) \
((pctxt->buffer.size > 0) ?  \
(((numElements * minElemBits) > (pctxt->buffer.size * 8)) ? \
ASN_E_INVLEN : 0) : 0)

/** @defgroup perdecruntime PER C Decode Functions.
 * @{
 *
 * PER runtime library decode functions handle the decoding of the primitive
 * ASN.1 data types and length variables. Calls to these functions are
 * assembled in the C source code generated by the ASN1C complier 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 item
 * exists.
 *
 * The procedure to decode a primitive data item is as follows:
 *   -# Call the pu_newContext or pu_initContext function to specify the
 * address of the buffer containing the encoded ASN.1 data to be decoded and
 * whether the data is aligned, or unaligned.
 *   -# Call the specific decode function to decode the value.
 */

/**
 * This function will decode a single bit a place the result in an ASN.1
 * BOOLEAN type variable.
 *
 * @param pctxt       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 pvalue       A pointer to the BOOLEAN value to receive the decoded
 *                       result.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_bit (OSCTXT* pctxt, OSBOOL* pvalue);

/**
 * This function will decode a series of multiple bits and place the results in
 * an unsigned integer variable.
 *
 * @param pctxt       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 pvalue       A pointer to an unsigned integer variable to receive the
 *                       decoded result.
 * @param nbits        The number of bits to decode.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_bits 
(OSCTXT* pctxt, OSUINT32* pvalue, OSUINT32 nbits);

/**
 * This function decodes 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 hexadecimal strings starting with "0x" prefix. If it is
 * necessary to convert a hexadecimal string to another radix, then use the
 * ::rtxBigIntSetStr / ::rtxBigIntToString functions.
 *
 * @param pctxt        Pointer to context block structure.
 * @param ppvalue      Pointer to a character pointer variable to receive the
 *                       decoded unsigned value. Dynamic memory is allocated
 *                       for the variable using the ::rtxMemAlloc function. The
 *                       decoded variable is represented as a decimal string
 *                       starting with no prefix.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_BigInteger (OSCTXT *pctxt, const char** ppvalue);

/**
 * This variant of the pd_BigInteger function allows the user to select 
 * the radix of the decoded integer string.
 *
 * @param pctxt        Pointer to context block structure.
 * @param ppvalue      Pointer to a character pointer variable to receive the
 *                       decoded unsigned value. Dynamic memory is allocated
 *                       for the variable using the ::rtxMemAlloc function. The
 *                       decoded variable is represented as a decimal string
 *                       starting with no prefix.
 * @param radix        Radix to be used for decoded string.  Valid values 
 *                       are 2, 8, 10, or 16.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_BigIntegerEx (OSCTXT *pctxt, const char** ppvalue, int radix);

/**
 * This function will decode a value of the ASN.1 bit string type whose maximum
 * size is is known in advance. The ASN1C complier generates a call to this
 * function to decode bit string productions or elements that contain a size
 * constraint.
 *
 * @param pctxt       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 numbits_p    Pointer to an unsigned integer variable to receive
 *                       decoded number of bits.
 * @param buffer       Pointer to a fixed-size or pre-allocated array of bufsiz
 *                       octets to receive a decoded bit string.
 * @param bufsiz       Length (in octets) of the buffer to receive the decoded
 *                       bit string.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_BitString 
(OSCTXT* pctxt, OSUINT32* numbits_p, OSOCTET* buffer,
 OSUINT32 bufsiz);

/**
 * This function will decode a variable of the ASN.1 BMP character string. This
 * differs from the decode routines for the character strings previously
 * described in that the BMP string type is based on 16-bit characters. A
 * 16-bit character string is modeled using an array of unsigned short
 * integers.
 *
 * @param pctxt       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 pvalue       Pointer to character string structure to receive the
 *                       decoded result. The structure includes a count field
 *                       containing the number of characters and an array of
 *                       unsigned short integers to hold the 16-bit character
 *                       values.
 * @param permCharSet  A pointer to the constraining character set. This
 *                       contains an array containing all valid characters in
 *                       the set as well as the aligned and unaligned bit
 *                       counts required to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_BMPString 
(OSCTXT* pctxt, ASN1BMPString* pvalue, Asn116BitCharSet* permCharSet);

/**
 * This function will decode a variable of the ASN.1 32-bit character string.
 * This differs from the decode routines for the character strings previously
 * described because the universal string type is based on 32-bit characters. A
 * 32-bit character string is modeled using an array of unsigned integers.
 *
 * @param pctxt       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 pvalue       Pointer to character string structure to receive the
 *                       decoded result. The structure includes a count field
 *                       containing the number of characters and an array of
 *                       unsigned short integers to hold the 32-bit character
 *                       values.
 * @param permCharSet  A pointer to the constraining character set. This
 *                       contains an array containing all valid characters in
 *                       the set as well as the aligned and unaligned bit
 *                       counts required to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_UniversalString 
(OSCTXT* pctxt, ASN1UniversalString* pvalue, Asn132BitCharSet* permCharSet);

/**
 * This function will position the decode bit cursor on the next byte boundary.
 *
 * @param pctxt       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             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_byte_align (OSCTXT* pctxt);

/**
 * @param pctxt       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_p2    A pointer to an open type variable to receive the
 *                       decoded data.
 * @param pnumocts    A pointer to an unsigned buffer of bufsiz octets to
 *                       receive decoded data.
 */
EXTERNPER int pd_ChoiceOpenTypeExt 
(OSCTXT* pctxt, const OSOCTET** object_p2, OSUINT32* pnumocts);

/**
 * This function will decode an integer constrained either by a value or value
 * range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to integer variable to receive decoded value.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConsInteger 
(OSCTXT* pctxt, OSINT32* pvalue, OSINT32 lower, OSINT32 upper);

/**
 * This function will decode an 8-bit integer constrained either by a value or
 * value range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to 8-bit integer variable to receive decoded
 *                       value.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConsInt8 
(OSCTXT* pctxt, OSINT8* pvalue, OSINT32 lower, OSINT32 upper);

/**
 * This function will decode a 16-bit integer constrained either by a value or
 * value range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to 16-bit integer variable to receive decoded
 *                       value.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConsInt16 (OSCTXT* pctxt, 
                            OSINT16* pvalue, OSINT32 lower, OSINT32 upper);

/**
 * This function will decode a 64-bit integer constrained either by a value or
 * value range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to 64-bit integer variable to receive decoded
 *                       value.
 * @param lower        Lower range value, represented as 64-bit integer.
 * @param upper        Upper range value, represented as 64-bit integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConsInt64 (OSCTXT* pctxt, 
                            OSINT64* pvalue, OSINT64 lower, OSINT64 upper);

/**
 * This function will decode an unsigned integer constrained either by a value
 * or value range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to unsigned integer variable to receive decoded
 *                       value.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConsUnsigned 
(OSCTXT* pctxt, OSUINT32* pvalue, OSUINT32 lower, OSUINT32 upper);

/**
 * This function will decode an 8-bit unsigned integer constrained either by a
 * value or value range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to 8-bit unsigned integer variable to receive
 *                       decoded value.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConsUInt8 (OSCTXT* pctxt, 
                            OSUINT8* pvalue, OSUINT32 lower, OSUINT32 upper);

/**
 * This function will decode a 16-bit unsigned integer constrained either by a
 * value or value range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to 16-bit unsigned integer variable to receive
 *                       decoded value.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConsUInt16 
(OSCTXT* pctxt, OSUINT16* pvalue, OSUINT32 lower, OSUINT32 upper);

/**
 * This function will decode a 64-bit unsigned integer constrained either by a
 * value or value range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to 64-bit unsigned integer variable to receive
 *                       decoded value.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConsUInt64 (OSCTXT* pctxt, OSUINT64* pvalue, 
                             OSUINT64 lower, OSUINT64 upper);

/**
 * This function decodes a constrained whole number as specified in Section
 * 10.5 of the X.691 standard.
 *
 * @param pctxt             Pointer to context block structure.
 * @param padjusted_value    Pointer to unsigned adjusted integer value to
 *                             receive decoded result. To get the final value,
 *                             this value is added to the lower boundary of the
 *                             range.
 * @param range_value        Unsigned integer value specifying the total size
 *                             of the range. This is obtained by subtracting
 *                             the lower range value from the upper range
 *                             value.
 * @return                   Completion status of operation:
 *                             - 0 (0) = success,
 *                             - negative return value is error.
 */
EXTERNPER int pd_ConsWholeNumber 
(OSCTXT* pctxt, OSUINT32* padjusted_value, OSUINT32 range_value);

/**
 * This function decodes a constrained whole number as specified in Section
 * 10.5 of the X.691 standard, represented as 64-bit integer.
 *
 * @param pctxt             Pointer to context block structure.
 * @param padjusted_value    Pointer to 64-bit unsigned adjusted integer value
 *                             to receive decoded result. To get the final
 *                             value, this value is added to the lower boundary
 *                             of the range.
 * @param range_value        Unsigned 64-bit integer value specifying the total
 *                             size of the range. This is obtained by
 *                             subtracting the lower range value from the upper
 *                             range value.
 * @return                   Completion status of operation:
 *                             - 0 (0) = success,
 *                             - negative return value is error.
 */
EXTERNPER int pd_ConsWholeNumber64 
(OSCTXT* pctxt, OSUINT64* padjusted_value, OSUINT64 range_value);

/**
 * This function decodes a constrained string value. This is a deprecated
 * version of the function provided for backward compatibility.
 *
 * @param pctxt       Pointer to context block structure.
 * @param string       Pointer to const char* to receive decoded string. Memory
 *                       will be allocated for this variable using internal
 *                       memory management functions.
 * @param pCharSet     Pointer to a character set descriptor structure. This
 *                       contains an array containing all valid characters in
 *                       the set as well as the aligned and unaligned bit
 *                       counts required to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConstrainedString 
(OSCTXT* pctxt, const char** string, Asn1CharSet* pCharSet);

/**
 * This function decodes a constrained string value. This version of the
 * function allows all of the required permitted alphabet constraint parameters
 * to be passed in as arguments.
 *
 * @param pctxt       Pointer to context block structure.
 * @param string       Pointer to const char* to receive decoded string. Memory
 *                       will be allocated for this variable using internal
 *                       memory management functions.
 * @param charSet      String containing permitted alphabet character set. Can
 *                       be null if no character set was specified.
 * @param abits        Number of bits in a character set character (aligned).
 * @param ubits        Number of bits in a character set character (unaligned).
 * @param canSetBits   Number of bits in a character from the canonical set
 *                       representing this string.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ConstrainedStringEx 
(OSCTXT* pctxt, const char** string, const char* charSet,
 OSUINT32 abits, OSUINT32 ubits, OSUINT32 canSetBits);

/**
 * This function will encode a constrained ASN.1 character string. This
 * function is normally not called directly but rather is called from Useful
 * Type Character String encode functions that deal with 16-bit strings. The
 * only function that does not release is the pe_BMPString function.
 *
 * @param pctxt       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 pString      Character string to be encoded. The structure includes a
 *                       count field containing the number of characters to
 *                       encode and an array of unsigned short integers to hold
 *                       the 16-bit characters to be encoded.
 * @param pCharSet     Pointer to the constraining character set. This contains
 *                       an array containing all valid characters in the set as
 *                       well as the aligned and unaligned bit counts required
 *                       to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_16BitConstrainedString 
(OSCTXT* pctxt, Asn116BitCharString* pString, Asn116BitCharSet* pCharSet);

/**
 * This function will encode a constrained ASN.1 character string. This
 * function is normally not called directly but rather is called from Useful
 * Type Character String encode functions that deal with 32-bit strings. The
 * only function that does not release is the pe_UniversalString function.
 *
 * @param pctxt       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 pString      Character string to be encoded. The structure includes a
 *                       count field containing the number of characters to
 *                       encode and an array of unsigned short integers to hold
 *                       the 32-bit characters to be encoded.
 * @param pCharSet     Pointer to the constraining character set. This contains
 *                       an array containing all valid characters in the set as
 *                       well as the aligned and unaligned bit counts required
 *                       to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_32BitConstrainedString 
(OSCTXT* pctxt, Asn132BitCharString* pString, Asn132BitCharSet* pCharSet);

/**
 * This function will decode a variable of thr ASN.1 BIT STRING type. This
 * function allocates dynamic memory t store the decoded result. The ASN1C
 * complier generates a call to this function to decode an unconstrained bit
 * string production or element.
 *
 * @param pctxt       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 pBitStr      Pointer to a dynamic bit string structure to receive the
 *                       decoded result. This structure contains a field to
 *                       hold the number of decoded bits and a pointer to an
 *                       octet string to hold the decoded data. Memory is
 *                       allocated by the decoder using the rtxMemAlloc
 *                       function. This memory is tracked within the context
 *                       and released when the pu_freeContext function is
 *                       invoked.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_DynBitString 
(OSCTXT* pctxt, ASN1DynBitStr* pBitStr);

/**
 * This function will decode a value of the ASN.1 octet string type whose
 * maximum size is known in advance. The ASN1C complier generates a call to
 * this function to decode octet string productions or elements that contain a
 * size constraint.
 *
 * @param pctxt       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 pOctStr      A pointer to a dynamic octet string to receive the
 *                       decoded result.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_DynOctetString 
(OSCTXT* pctxt, ASN1DynOctStr* pOctStr);

/**
 * @param pctxt       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 itemBits     The size of the specific entity.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_GetComponentLength 
(OSCTXT* pctxt, OSUINT32 itemBits);

/**
 * This function will decode a length determinant value.
 *
 * @param pctxt       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 pvalue       A pointer to an unsigned integer variable to receive the
 *                       decoded length value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_Length (OSCTXT* pctxt, OSUINT32* pvalue);

/**
 * @param pctxt       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 bitOffset    The bit offset inside the message buffer.
 */
EXTERNPER int pd_moveBitCursor (OSCTXT* pctxt, int bitOffset);

/**
 * This function decodes a value of the ASN.1 object identifier type.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       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.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_ObjectIdentifier (OSCTXT* pctxt, ASN1OBJID* pvalue);

/**
 * This function decodes a value of the ASN.1 object identifier type using
 * 64-bit subidentifiers.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       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.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_oid64 (OSCTXT* pctxt, ASN1OID64* pvalue);

/**
 * This function decodes a value of the ASN.1 RELATIVE-OID type.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       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.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_RelativeOID (OSCTXT* pctxt, ASN1OBJID* pvalue);

/**
 * This function will decode a value of the ASN.1 octet string type whose
 * maximun size is known in advance. The ASN1C compiler generates a call to
 * this function to decode octet string productions or elements that contain a
 * size constraint.
 *
 * @param pctxt       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 pnumocts    A pointer to an unsigned buffer of bufsiz octets to
 *                       receive decoded data.
 * @param buffer       A pointer to a pre-allocated buffer of size octets to
 *                       receive the decoded data.
 * @param bufsiz       The size of the buffer to receive the decoded result.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_OctetString 
(OSCTXT* pctxt, OSUINT32* pnumocts, OSOCTET* buffer,
 OSUINT32 bufsiz);

/**
 * This function will decode an ASN.1 open type. This used to be the ASN.1 ANY
 * type, but now is used in a variety of applications requiring an encoding that
 * can be interpreted by a decoder without prior knowledge of the type of the
 * variable.
 *
 * @param pctxt       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 pnumocts    A pointer to an unsigned buffer of bufsiz octets to
 *                       receive decoded data.
 * @param object_p2    A pointer to an open type variable to receive the
 *                       decoded data.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_OpenType 
(OSCTXT* pctxt, const OSOCTET** object_p2, OSUINT32* pnumocts);

/**
 * This function will decode an ASN.1 open type extension. These are extra
 * fields in a version-2 message that may be present after the ... extension
 * marker. An open type structure (extElem1) is added to a message structure
 * that contains an extension marker but no extension elements. The
 * pd_OpenTypeExt function will populate this structure with the complete
 * extension information (optional bit or choice index, length and data). A
 * subsequent call to pe_OpenTypeExt will cause the saved extension fields to
 * be included in a newly encoded message of the given type.
 *
 * @param pctxt       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_p2    A pointer to an open type variable to receive the
 *                       decoded data.
 * @param pnumocts    A pointer to an unsigned buffer of bufsiz octets to
 *                       receive decoded data.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_OpenTypeExt 
(OSCTXT* pctxt, const OSOCTET** object_p2, OSUINT32* pnumocts);

/**
 * This function will decode a value of the binary encoded ASN.1 real type. 
 * This function provides support for the plus-infinity special real values.
 *
 * @param pctxt       Pointer to a context structure. This provides a storage
 *                       area for the function to store all workings variables
 *                       that must be maintained between function calls.
 * @param pvalue       Pointer to an real variable to receive decoded
 *                       value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_Real 
(OSCTXT* pctxt, OSREAL* pvalue);

/**
 * This function will decode a small non-negative whole number as specified in
 * Section 10.6 of the X.691 standard. This is a number that is expected to be
 * small, but whose size is potentially unlimited due to the presence of an
 * extension maker.
 *
 * @param pctxt       Pointer to a context structure. This provides a storage
 *                       area for the function to store all workings variables
 *                       that must be maintained between function calls.
 * @param pvalue       Pointer to an unsigned integer value to receive decoded
 *                       results.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_SmallNonNegWholeNumber 
(OSCTXT* pctxt, OSUINT32* pvalue);

/**
 * This function will decode a semi-constrained integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to integer variable to receive decoded value.
 * @param lower        Lower range value, represented as signed
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_SemiConsInteger 
   (OSCTXT* pctxt, OSINT32* pvalue, OSINT32 lower);

/**
 * This function will decode a semi-constrained unsigned integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to unsigned integer variable to receive decoded
 *                       value.
 * @param lower        Lower range value, represented as unsigned
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_SemiConsUnsigned 
   (OSCTXT* pctxt, OSUINT32* pvalue, OSUINT32 lower);

/**
 * This function will decode a semi-constrained 64-bit integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to 64-bit integer variable to receive decoded
 *                       value.
 * @param lower        Lower range value, represented as signed 64-bit
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_SemiConsInt64 
   (OSCTXT* pctxt, OSINT64* pvalue, OSINT64 lower);

/**
 * This function will decode a semi-constrained unsigned 64-bit integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to unsigned 64-bit integer variable to receive
 *                       decoded value.
 * @param lower        Lower range value, represented as unsigned 64-bit
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_SemiConsUInt64 
   (OSCTXT* pctxt, OSUINT64* pvalue, OSUINT64 lower);


/**
 * This function will decode an unconstrained integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to integer variable to receive decoded value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_UnconsInteger (OSCTXT *pctxt, OSINT32* pvalue);

/**
 * This function will decode an unconstrained unsigned integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to unsigned integer variable to receive decoded
 *                       value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
#define pd_UnconsUnsigned(pctxt,pvalue) \
pd_SemiConsUnsigned(pctxt, pvalue, 0U)

/**
 * This function will decode an unconstrained 64-bit integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to 64-bit integer variable to receive decoded
 *                       value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_UnconsInt64 (OSCTXT *pctxt, OSINT64* pvalue);

/**
 * This function will decode an unconstrained unsigned 64-bit integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       Pointer to unsigned 64-bit integer variable to receive
 *                       decoded value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
#define pd_UnconsUInt64(pctxt,pvalue) \
pd_SemiConsUInt64(pctxt, pvalue, 0)

/**
 * This function will decode a variable of the ASN.1 character string. 
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue      Pointer to a character pointer variable to receive the
 *                       decoded result. Dynamic memory is allocated
 *                       for the variable using the ::rtxMemAlloc function.
 * @return            Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_VarWidthCharString (OSCTXT* pctxt, const char** pvalue);

/**
 * This function will decode a value of the decimal encoded ASN.1 real type. 
 *
 * @param pctxt       Pointer to a context structure. This provides a storage
 *                       area for the function to store all workings variables
 *                       that must be maintained between function calls.
 * @param ppvalue      Pointer to a character pointer variable to receive the
 *                       decoded result. Dynamic memory is allocated
 *                       for the variable using the ::rtxMemAlloc function.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pd_Real10 (OSCTXT *pctxt, const char** ppvalue); 

/** @} perdecruntime */

/* Encode functions */
/** @defgroup perencruntime PER C Encode Functions.
 * @{
 *
 * The Per low-level encode functions handle the PER encoding of the primitive
 * ASN.1 data types. 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 a low-level encode function is the same as the
 * procedure to call a compiler generated encode function described above. The
 * pu_newContext function must first be called to set a pointer to the buffer
 * into which the variable is to be encoded. A static encode buffer is
 * specified by assigning a pointer to a buffer and a buffer size. Setting the
 * buffer address to NULL and buffer size to 0 specifies a dynamic buffer. The
 * encode function is then invoked. The result of the encoding will start at
 * the beginning of the specified buffer, or, if a dynamic buffer was used,
 * only be obtained by calling pe_GetMsgPtr. The length of the encoded compound
 * is obtained by calling pe_GetMsgLen.
 */

/**
 * This function will encode a constrained ASN.1 character string. This
 * function is normally not called directly but rather is called from Useful
 * Type Character String encode functions that deal with 16-bit strings. The
 * only function that does that in this release is the pe_BMPString function.
 *
 * @param pctxt       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 value        Character string to be encoded. The structure includes a
 *                       count field containing the number of characters to
 *                       encode and an array of unsigned short integers to hold
 *                       the 16-bit characters to be encoded.
 * @param pCharSet     Pointer to the constraining character set. The contains
 *                       an array containing all valid characters in the set as
 *                       well as the aligned and unaligned bit counts required
 *                       to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_16BitConstrainedString 
(OSCTXT* pctxt, Asn116BitCharString value, Asn116BitCharSet* pCharSet);

/**
 * This function will encode a constrained ASN.1 character string. This
 * function is normally not called directly but rather is called from Useful
 * Type Character String encode functions that deal with 32-bit strings. The
 * only function that does that in this release is the pe_UniversalString
 * function.
 *
 * @param pctxt       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 value        Character string to be encoded. The structure includes a
 *                       count field containing the number of characters to
 *                       encode and an array of unsigned short integers to hold
 *                       the 32-bit characters to be encoded.
 * @param pCharSet     Pointer to the constraining character set. The contains
 *                       an array containing all valid characters in the set as
 *                       well as the aligned and unaligned bit counts required
 *                       to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_32BitConstrainedString 
(OSCTXT* pctxt, Asn132BitCharString value, Asn132BitCharSet* pCharSet);

/**
 * This function encodes a two's complement binary integer as specified in
 * Section 10.4 of the X.691 standard.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Signed integer value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_2sCompBinInt 
(OSCTXT* pctxt, OSINT32 value);

/**
 * This function encodes a two's complement binary 64-bit integer as specified
 * in Section 10.4 of the X.691 standard.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Signed 64-bit integer value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_2sCompBinInt64 (OSCTXT* pctxt, OSINT64 value);

/**
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       A pointer to a character string containing the value to
 *                       be encoded.
 * @param nocts        The number of octets.
 */
EXTERNPER int pe_aligned_octets 
(OSCTXT* pctxt, OSOCTET* pvalue, OSUINT32 nocts);

/**
 * The pe_BigInteger function will encode 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 pctxt       Pointer to context block structure.
 * @param pvalue       A pointer to a character string containing the value to
 *                       be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_BigInteger 
(OSCTXT* pctxt, const char* pvalue);

/**
 * This function will encode a varialbe of the ASN.1 BOOLEAN type in single
 * bit,
 *
 * @param pctxt       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 value        The BOOLEAN value to be encoded.
 */
EXTERNPER int pe_bit 
(OSCTXT* pctxt, OSBOOL value);

/**
 * This function encodes multiple bits.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Unsigned integer containing the bits to be encoded.
 * @param nbits        Number of bits in value to encode.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_bits 
(OSCTXT* pctxt, OSUINT32 value, OSUINT32 nbits);

/**
 * This function encodes multiple bits, using unsigned 64-bit integer to hold
 * bits.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Unsigned 64-bit integer containing the bits to be
 *                       encoded.
 * @param nbits        Number of bits in value to encode.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_bits64 (OSCTXT* pctxt, OSUINT64 value, OSUINT32 nbits);

/**
 * This function will encode a value of the ASN.1 bit string type.
 *
 * @param pctxt       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 numocts      The number of bits n the string to be encoded.
 * @param data         Pointer to the bit string data to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_BitString 
(OSCTXT* pctxt, OSUINT32 numocts, const OSOCTET* data);

/**
 * This function will encode a variable of the ASN.1 BMP character string. This
 * differs from the encode routines for the character strings previously
 * described in that the BMP string type is based on 16-bit characters. A
 * 16-bit character string is modeled using an array of unsigned short
 * integers.
 *
 * @param pctxt       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 value        Character string to be encoded. This structure includes
 *                       a count field containing the number of characters to
 *                       encode and an array of unsigned short integers to hold
 *                       the 16-bit characters to be encoded.
 * @param permCharSet  Pointer to the constraining character set. This contains
 *                       an array containing all valid characters in the set as
 *                       well as the aligned and unaligned bit counts required
 *                       to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_BMPString 
(OSCTXT* pctxt, ASN1BMPString value, Asn116BitCharSet* permCharSet);

/**
 * This function will encode a variable of the ASN.1 Universal character
 * string. This differs from the encode routines for the character strings
 * previously described in that the Universal string type is based on 32-bit
 * characters. A 32-bit character string is modeled using an array of unsigned
 * integers.
 *
 * @param pctxt       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 value        Character string to be encoded. The structure includes a
 *                       count field containing all valid characters in the set
 *                       as well as the aligned and unaligned bit counts
 *                       required to encode the characters.
 * @param permCharSet  A pointer to the constraining character set. This
 *                       contains an array containing all valid characters in
 *                       the set as well as the aligned and the unaligned bit
 *                       counts required to encode the characters.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_UniversalString 
(OSCTXT* pctxt, ASN1UniversalString value, Asn132BitCharSet* permCharSet);

/**
 * This function will position the encode bit cursor on the next byte boundry.
 *
 * @param pctxt       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             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_byte_align (OSCTXT* pctxt);

/**
 * This function will determine if the given number of bytes will fit in the
 * encode buffer. If not, either the buffer is expanded (if it is a dynamic
 * buffer) or an error is signaled.
 *
 * @param pctxt       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       Number of bytes of space required to hold the variable
 *                       to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_CheckBuffer (OSCTXT* pctxt, size_t nbytes);

/**
 * @param pctxt       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 numocts      Number of octets in the string to be encoded.
 * @param data         Pointer to octet string data to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ChoiceTypeExt 
(OSCTXT* pctxt, OSUINT32 numocts, const OSOCTET* data);

/**
 * This function encodes an integer constrained either by a value or value
 * range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ConsInteger 
(OSCTXT* pctxt, OSINT32 value, OSINT32 lower, OSINT32 upper);

/**
 * This function encodes a 64-bit integer constrained either by a value or
 * value range constraint.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded, represented as 64-bit integer.
 * @param lower        Lower range value, represented as 64-bit integer.
 * @param upper        Upper range value, represented as 64-bit integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ConsInt64 (OSCTXT* pctxt, 
                            OSINT64 value, OSINT64 lower, OSINT64 upper);

/**
 * This function encodes a constrained string value. This is a deprecated
 * version of the function provided for backward compatibility.
 *
 * @param pctxt       Pointer to context block structure.
 * @param string       Pointer to string to be encoded.
 * @param pCharSet     Pointer to a character set descriptor structure.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ConstrainedString 
(OSCTXT* pctxt, const char* string, Asn1CharSet* pCharSet);

/**
 * This function encodes a constrained string value. This version of the
 * function allows all of the required permitted alphabet constraint parameters
 * to be passed in as arguments.
 *
 * @param pctxt       Pointer to context block structure.
 * @param string       Pointer to string to be encoded.
 * @param charSet      String containing permitted alphabet character set. Can
 *                       be null if no character set was specified.
 * @param abits        Number of bits in a character set character (aligned).
 * @param ubits        Number of bits in a character set character (unaligned).
 * @param canSetBits   Number of bits in a character from the canonical set
 *                       representing this string.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ConstrainedStringEx 
(OSCTXT* pctxt, const char* string, const char* charSet,
 OSUINT32 abits, OSUINT32 ubits, OSUINT32 canSetBits);

/**
 * This function encodes an unsigned integer constrained either by a value or
 * value range constraint. The constrained unsigned integer option is used if:
 *
 * 1. The lower value of the range is >= 0, and 2. The upper value of the range
 * is >= MAXINT
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded.
 * @param lower        Lower range value.
 * @param upper        Upper range value.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ConsUnsigned 
(OSCTXT* pctxt, OSUINT32 value, OSUINT32 lower, OSUINT32 upper);

/**
 * This function encodes an unsigned 64-bit integer constrained either by a
 * value or value range constraint. The constrained unsigned integer option is
 * used if:
 *
 * 1. The lower value of the range is >= 0, and 2. The upper value of the range
 * is >= MAXINT
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded, represented as unsigned 64-bit
 *                       integer.
 * @param lower        Lower range value, represented as unsigned 64-bit
 *                       integer.
 * @param upper        Upper range value, represented as unsigned 64-bit
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ConsUInt64 (OSCTXT* pctxt, OSUINT64 value, 
                             OSUINT64 lower, OSUINT64 upper);

/**
 * This function encodes a constrained whole number as specified in Section
 * 10.5 of the X.691 standard.
 *
 * @param pctxt            Pointer to context block structure.
 * @param adjusted_value    Unsigned adjusted integer value to be encoded. The
 *                            adjustment is done by subtracting the lower value
 *                            of the range from the value to be encoded.
 * @param range_value       Unsigned integer value specifying the total size of
 *                            the range. This is obtained by subtracting the
 *                            lower range value from the upper range value.
 * @return                  Completion status of operation:
 *                            - 0 (0) = success,
 *                            - negative return value is error.
 */
EXTERNPER int pe_ConsWholeNumber 
(OSCTXT* pctxt, OSUINT32 adjusted_value, OSUINT32 range_value);

/**
 * This function encodes a constrained whole number as specified in Section
 * 10.5 of the X.691 standard, represented as 64-bit integer.
 *
 * @param pctxt            Pointer to context block structure.
 * @param adjusted_value    Unsigned adjusted integer value to be encoded. The
 *                            adjustment is done by subtracting the lower value
 *                            of the range from the value to be encoded.
 * @param range_value       Unsigned integer value specifying the total size of
 *                            the range. This is obtained by subtracting the
 *                            lower range value from the upper range value.
 * @return                  Completion status of operation:
 *                            - 0 (0) = success,
 *                            - negative return value is error.
 */
EXTERNPER int pe_ConsWholeNumber64 
(OSCTXT* pctxt, OSUINT64 adjusted_value, OSUINT64 range_value);

/**
 * This function will expand the buffer to hold the given number of bytes.
 *
 * @param pctxt       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 the buffer is to be expanded by.
 *                       Note that the buffer will be expanded by
 *                       ASN_K_ENCBIFXIZ or nbytes (whichever is larger.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ExpandBuffer (OSCTXT* pctxt, size_t nbytes);

/**
 * @param value        Length value to be encoded.
 */
EXTERNPER OSUINT32 pe_GetIntLen (OSUINT32 value);

/**
 * @param pctxt       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.
 */
EXTERNPER size_t pe_GetMsgBitCnt (OSCTXT* pctxt);

/**
 * This function will return the message pointer and length of an encoded
 * message. This function is called after a complier generated encode function
 * to get the pointer and length of the message. It is normally used when
 * dynamic encoding is specified because the message pointer is not known until
 * encoding is complete. If static encoding is used, the message starts at the
 * beginning of the specified buffer adn the pe_GetMsgLen function can be used
 * to obtain the lenght of the message.
 *
 * @param pctxt       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 pLength      Pointer to variable to receive length of the encoded
 *                       message.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER OSOCTET* pe_GetMsgPtr (OSCTXT* pctxt, OSINT32* pLength);

/**
 * @param pctxt       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 pLength      Pointer to variable to receive length of the encoded
 *                       message.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER OSOCTET* pe_GetMsgPtrU (OSCTXT* pctxt, OSUINT32* pLength);

/**
 * This function will encode a length determinant value.
 *
 * @param pctxt       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 value        Length value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_Length (OSCTXT* pctxt, OSUINT32 value);

/**
 * This function encodes a non-negative binary integer as specified in Section
 * 10.3 of the X.691 standard.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Unsigned integer value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_NonNegBinInt (OSCTXT* pctxt, OSUINT32 value);

/**
 * This function encodes a non-negative binary 64-bit integer as specified in
 * Section 10.3 of the X.691 standard.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Unsigned 64-bit integer value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_NonNegBinInt64 (OSCTXT* pctxt, OSUINT64 value);

/**
 * This function encodes a value of the ASN.1 object identifier type.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       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 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_ObjectIdentifier (OSCTXT* pctxt, ASN1OBJID* pvalue);

#ifndef _NO_INT64_SUPPORT
/**
 * This function encodes a value of the ASN.1 object identifier type, using
 * 64-bit subidentifiers.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       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 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_oid64 (OSCTXT* pctxt, ASN1OID64* pvalue);
#endif

/**
 * This function encodes a value of the ASN.1 RELATIVE-OID type.
 *
 * @param pctxt       Pointer to context block structure.
 * @param pvalue       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 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_RelativeOID (OSCTXT* pctxt, ASN1OBJID* pvalue);

/**
 * This fuction will encode an array of octets. The Octets will be encoded
 * unaligned starting at the current bit offset within the encode buffer.
 *
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param pvalue       A pointer to an array of octets to encode
 * @param nbits        The number of Octets to encode
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_octets 
(OSCTXT* pctxt, const OSOCTET* pvalue, OSUINT32 nbits);

/**
 * This function will encode a value of the ASN.1 octet string type.
 *
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param numocts      Number of octets in the string to be encoded.
 * @param data         Pointer to octet string data to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_OctetString 
(OSCTXT* pctxt, OSUINT32 numocts, const OSOCTET* data);

/**
 * This function will encode an ASN.1 open type. This used to be the ANY type,
 * but now is used in a variety of applications requiring an encoding that can
 * be interpreted by a decoder without a prior knowledge of the type of the
 * variable.
 *
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param numocts      Number of octets in the string to be encoded.
 * @param data         Pointer to octet string data to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_OpenType 
(OSCTXT* pctxt, OSUINT32 numocts, const OSOCTET* data);

/**
 * This function will encode an ASN.1 open type extension. An open type
 * extension field is the data that potentially resides after the ... marker in
 * a version-1 message. The open type structure contains a complete encoded bit
 * set including option element bits or choice index, length, and data.
 * Typically, this data is populated when a version-1 system decodes a
 * version-2 message. The extension fields are retained and can then be
 * re-encoded if a new message is to be sent out (for example, in a store and
 * forward system).
 *
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param pElemList    A pointer to the open type to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_OpenTypeExt 
(OSCTXT* pctxt, OSRTDList* pElemList);

/**
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param pElemList    A pointer to the open type to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_OpenTypeExtBits 
(OSCTXT* pctxt, OSRTDList* pElemList);

/**
 * This function will encode a value of the ASN.1 real type. This function
 * provides support for the plus-infinity and minus-infinity special real
 * values. Use the rtxGetPlusInfinity or rtxGetMinusInfinity functions to get
 * these special values.
 *
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param value        Value to be encoded. Special real values plus and minus
 *                       infinity are encoded by using the rtxGetPlusInfinity
 *                       and the rtxGetMinusInfinity functions to se the real
 *                       value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_Real (OSCTXT* pctxt, OSREAL value);

/**
 * This function will endcode a small, non-negative whole number as specified
 * in Section 10.6 of teh X.691 standard. This is a number that is expected to
 * be small, but whose size is potentially unlimited due to the presence of an
 * extension marker.
 *
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param value        An unsigned integer value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_SmallNonNegWholeNumber (OSCTXT* pctxt, OSUINT32 value);

/**
 * This function encodes an semi-constrained integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded.
 * @param lower        Lower range value, represented as signed
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_SemiConsInteger 
   (OSCTXT* pctxt, OSINT32 value, OSINT32 lower);

#ifndef _NO_INT64_SUPPORT
/**
 * This function encodes an semi-constrained 64-bit integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded, represented as 64-bit integer.
 * @param lower        Lower range value, represented as signed 64-bit
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_SemiConsInt64 
   (OSCTXT* pctxt, OSINT64 value, OSINT64 lower);
#endif

/**
 * This function encodes an semi-constrained unsigned integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded.
 * @param lower        Lower range value, represented as unsigned
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_SemiConsUnsigned 
   (OSCTXT* pctxt, OSUINT32 value, OSUINT32 lower);

#ifndef _NO_INT64_SUPPORT
/**
 * This function encodes an semi-constrained unsigned 64-bit integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded, represented as unsigned 64-bit
 *                       integer.
 * @param lower        Lower range value, represented as unsigned 64-bit
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_SemiConsUInt64 
   (OSCTXT* pctxt, OSUINT64 value, OSUINT64 lower);
#endif

/**
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param value        Value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_UnconsLength (OSCTXT* pctxt, OSUINT32 value);

/**
 * This function encodes an unconstrained integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_UnconsInteger (OSCTXT* pctxt, OSINT32 value);

#ifndef _NO_INT64_SUPPORT
/**
 * This function encodes an unconstrained 64-bit integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded, represented as 64-bit integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_UnconsInt64 (OSCTXT* pctxt, OSINT64 value);
#endif

/**
 * This function encodes an unconstrained unsigned integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_UnconsUnsigned (OSCTXT* pctxt, OSUINT32 value);

#ifndef _NO_INT64_SUPPORT
/**
 * This function encodes an unconstrained unsigned 64-bit integer.
 *
 * @param pctxt       Pointer to context block structure.
 * @param value        Value to be encoded, represented as unsigned 64-bit
 *                       integer.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_UnconsUInt64 (OSCTXT* pctxt, OSUINT64 value);
#endif

/**
 * This function will encode a ASN.1 character string.
 *
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param value       A pointer to a character string containing the value to
 *                       be encoded.
 * @return            Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_VarWidthCharString (OSCTXT* pctxt, const char* value); 

/**
 * This function will encode a number from character string to ASN.1 real type
 * using decimal encoding. Number may be represented in integer, decimal, and 
 * exponent formats.
 *
 * @param pctxt       A pointer to a context structure. The provides a storage
 *                       area for the function to store all working variables
 *                       that must be maintained between function calls.
 * @param pvalue       Value to be encoded.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pe_Real10 (OSCTXT* pctxt, const char* pvalue);

/** @} perencruntime */

/* Utility functions */


/**
 * @defgroup perutil PER C Utility Functions 
 * @{
 *
 * The PER utility functions are common routines used by both the PER encode
 * and decode functions.
 */

/**
 * This function is used to add size to a context variable.
 *
 * @param pctxt       A pointer to a context structure. The referenced size
 *                       constraint is added to this structure for use by a
 *                       subsequent encode or decode function.
 * @param pSize        A pointer to the size constraint to add the context
 *                       variable.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pu_addSizeConstraint (OSCTXT* pctxt, Asn1SizeCnst* pSize);

EXTERNPER OSBOOL pu_alignCharStr 
(OSCTXT* pctxt, OSUINT32 len, OSUINT32 nbits, Asn1SizeCnst* pSize);

/**
 * @param pctxt       A pointer to a context structure. The referenced size
 *                       constraint is added to this structure for use by a
 *                       subsequent encode or decode function.
 * @param size         The size constraint to add the context variable.
 */
EXTERNPER int pu_checkSizeConstraint(OSCTXT* pctxt, int size);

/**
 * @param value        Value to be encoded.
 */
EXTERNPER OSUINT32 pu_bitcnt (OSUINT32 value);

EXTERNPER Asn1SizeCnst* pu_checkSize 
(Asn1SizeCnst* pSizeList, OSUINT32 value, OSBOOL* pExtendable);

/**
 * This function releases all dynamicmemeory associated with a context. This
 * function should be called even if the referenced context variable is not
 * dynamic. The reason is because it frees memory allocated within the context
 * as well as the context structure (it will only try to free the context
 * structure if it detects that it was previously allocated using the
 * pu_newContext function).
 *
 * @param pctxt       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.
 */
EXTERNPER void pu_freeContext (OSCTXT* pctxt);


/**
 * @param pctxt       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.
 */
EXTERNPER int  pu_getBitOffset (OSCTXT* pctxt);


EXTERNPER size_t pu_getMaskAndIndex (size_t bitOffset, unsigned char* pMask);

/**
 * This function will return the number of bits in a encoded message. This
 * function is called after a complier generated encode function is called to
 * get the bit count of the encoded component.
 *
 * @param pctxt       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             Length (in bits) of encoded message content.
 */
EXTERNPER size_t pu_getMsgLen (OSCTXT* pctxt);

/**
 * This function provides a standard hesadecimal dump of the contents of the
 * buffer currently specified in the given context.
 *
 * @param pctxt       Pointer to a context structure. The contents of the
 *                       encode or decode buffer that was specified in the call
 *                       to pu_initContext or pu_newContext is dumped.
 */
EXTERNPER void pu_hexdump (OSCTXT* pctxt);

EXTERNPER int pu_setBuffer 
(OSCTXT* pctxt, OSOCTET* bufaddr, size_t bufsiz, OSBOOL aligned);

EXTERNPER int pe_setp (OSCTXT* pctxt,
             OSOCTET* bufaddr, size_t bufsiz, OSBOOL aligned);



#define pd_setp(pctxt, bufaddr, bufsiz, aligned) \
   pu_setBuffer(pctxt, bufaddr, bufsiz, aligned)
#define pe_resetp(pctxt)   rtxResetContext(pctxt)
#define pd_resetp(pctxt)   rtxResetContext(pctxt)



/**
 * This function is used to initialize a pre-allocated OSCTXT structure. This
 * can be an OSCTXT variable declared on the stack or a pointer to an
 * OSCTXT structure that was previously allocated. This function sets all
 * internal variables within the structure to their initial values.
 *
 * @param pctxt       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 bufaddr      For encoding, this is the address of a buffer to receive
 *                       the encoded PER message (note: this is optional, if
 *                       specified to NULL a dynamic buffer will be allocated).
 *                       For decoding, this is that address of the buffer that
 *                       contains the PER message to be decoded.
 * @param bufsiz       For encoding, this is the size of the encoded buffer
 *                       (note: this is optional, if the bufaddr arguement is
 *                       specified to NULL, then dynamic encoding is in effect
 *                       and the buffer size is indefinite). For decoding, this
 *                       is the length (in octets) of the PER message to be
 *                       decoded.
 * @param aligned      A Boolean value specifying whether aligned or unaligned
 *                       encoding should be performed.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pu_initContext 
(OSCTXT* pctxt, OSOCTET* bufaddr, OSUINT32 bufsiz, OSBOOL aligned);

/**
 * This function is used to initialize the buffer of an OSCTXT structure with
 * buffer data from a second context structure. This function copies the buffer
 * information from the source context buffer to the destination structure. The
 * non-buffer related fields in the context remain untouched.
 *
 * @param pTarget      A pointer to the target context structure. Buffer
 *                       information within this structure is updated with data
 *                       from the source context.
 * @param pSource      A pointer to the source context structure. Buffer
 *                       information from the source context structure is
 *                       copied to the target structure.
 * @return             Completion status of operation:
 *                       - 0 (0) = success,
 *                       - negative return value is error.
 */
EXTERNPER int pu_initContextBuffer (OSCTXT* pTarget, OSCTXT* pSource);

EXTERNPER const char* pu_getFullName 
(OSCTXT* pctxt, const char* suffix);

EXTERNPER Asn1SizeCnst* pu_getSizeConstraint 
(OSCTXT* pctxt, OSBOOL extbit);

EXTERNPER void pu_init16BitCharSet 
(Asn116BitCharSet* pCharSet, OSUNICHAR first, OSUNICHAR last, 
 OSUINT32 abits, OSUINT32 ubits);

/**
 * @param pctxt       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.
 */
EXTERNPER void pu_insLenField (OSCTXT* pctxt);

/**
 * @param pSizeList    A pointer to the size of the Linked List.
 */
EXTERNPER OSBOOL pu_isExtendableSize (Asn1SizeCnst* pSizeList);

/**
 * @param pSizeList    A pointer to the size of the Linked List.
 */
EXTERNPER OSBOOL pu_isFixedSize (Asn1SizeCnst* pSizeList);

/**
 * This function is similar to the pu_initContext function in that it
 * initializes a context variable. The difference is that this function
 * allocates a new structure and then initializes it. It is equivalent to
 * calling malloc to allocate a context structure and then calling
 * pu_initContext to initialize it.
 *
 * @param bufaddr      For encoding, this is the address of a buffer to receive
 *                       the encoded PER message (note: this is optional, if
 *                       specified as NULL a dynamic buffer will be allocated).
 *                       For decoding, this is that address of the buffer that
 *                       contains the PER message to be decoded.
 * @param bufsiz       For encoding, this is the size of the encoded buffer
 *                       (note: this is optional, if the bufaddr argument is
 *                       specified to NULL, then dynamic encoding is in effect
 *                       and the buffer size is indefinite). For decoding, this
 *                       is the length (in octets) of the PER message to be
 *                       decoded.
 * @param aligned      A Boolean value specifying whether aligned or unaligned
 *                       encoding should be performed.
 * @return             A pointer to OSCTXT structure to receive the allocated
 *                       structure. NULL is returned if any error occurs in
 *                       allocating or initializing the context.
 */
EXTERNPER OSCTXT* pu_newContext 
(OSOCTET* bufaddr, OSUINT32 bufsiz, OSBOOL aligned);

EXTERNPER PERField* pu_newField 
(OSCTXT* pctxt, const char* nameSuffix);

/**
 * @param pctxt       A pointer to a context structure.
 */
EXTERNPER void pu_popName (OSCTXT* pctxt);

/**
 * Pushs an element on the stack.
 *
 * @param pctxt       A pointer to a context structure.
 * @param index        The location to insert the element.
 */
EXTERNPER void pu_pushElemName (OSCTXT* pctxt, int index);

/**
 * @param pctxt       A pointer to a context structure.
 * @param name         A pointer to the element to add to the stack.
 */
EXTERNPER void pu_pushName (OSCTXT* pctxt, const char* name);


EXTERNPER void pu_setBitOffset (OSCTXT* pctxt, int bitOffset);

/**
 * This function sets a permitted alphabet character set. This is the resulting
 * set of characters when the character associated with a standard character
 * string type is merged with a permitted alphabet constraint.
 *
 * @param pCharSet     A pointer to a character set structure describing the
 *                       character set currently associated with the character
 *                       string type. The resulting character set structure
 *                       after being merged with the permSet parameter.
 * @param permSet      A null-terminated string of permitted characters.
 */
EXTERNPER void pu_setCharSet (Asn1CharSet* pCharSet, const char* permSet);

/**
 * This function sets a permitted alphabet character set for 16-bit character
 * strings. This is the resulting set of character when the character
 * associated with a 16-bit string type is merged with a permitted alphabet
 * constraint.
 *
 * @param pctxt       Pointer to a context structure.
 * @param pCharSet     Pointer to a character set structure describing the
 *                       character set currently associated with the character
 *                       string type. The resulting character set structure
 *                       after being merged with the permSet parameter.
 * @param pAlphabet    Pointer to a structure describing the 16-bit permitted
 *                       alphabet.
 */
EXTERNPER void pu_set16BitCharSet 
(OSCTXT* pctxt, Asn116BitCharSet* pCharSet, Asn116BitCharSet* pAlphabet);


/**
 * @param pCharSet     Pointer to a character set structure describing the
 *                       character set currently associated with the character
 *                       string type. The resulting character set structure
 *                       after being merged with the permSet parameter.
 * @param firstChar    The first character in the range.
 * @param lastChar     The last character in the range.
 */
EXTERNPER void pu_set16BitCharSetFromRange 
(Asn116BitCharSet* pCharSet, OSUINT16 firstChar, OSUINT16 lastChar);

/**
 * @param pctxt       A pointer to a context structure.
 */
EXTERNPER void pu_setFldBitCount (OSCTXT* pctxt);


/**
 * @param pctxt       A pointer to a context structure.
 */
EXTERNPER void pu_setFldBitOffset (OSCTXT* pctxt);

/**
 * @param pCtxt        A pointer to a context structure.
 * @param value        The BOOLEAN value to be encoded.
 */
EXTERNPER OSBOOL pu_setTrace (OSCTXT* pCtxt, OSBOOL value);

/**
 * This function provides a detailed binary dump of the contents of the buffer
 * currently specified in the given context. The list of fields dumped by this
 * function was previously built up within the context using calls pu_newField,
 * pu_pushName, and pu_popName. These calls are built into both
 * compiler-generated and low-level PER encode/decode functions to trace the
 * actual bit encoding of a given construct.
 *
 * @param pctxt       A pointer to a context structure. The contents of the
 *                       encode or decode buffer that was specified in the call
 *                       to pu_initContext or pu_newContext is dumped.
 * @param varname      The name of the top-level variable name of the structure
 *                       being dumped.
 */
EXTERNPER void pu_bindump (OSCTXT* pctxt, const char* varname);
EXTERNPER void pu_dumpField 
(OSCTXT* pctxt, PERField* pField, const char* varname, 
 size_t nextBitOffset, BinDumpBuffer* pbuf);

EXTERNPER void pu_init32BitCharSet 
(Asn132BitCharSet* pCharSet, OS32BITCHAR first, OS32BITCHAR last, 
 OSUINT32 abits, OSUINT32 ubits);

/**
 * This function sets a permitted alphabet character set for 32-bit character
 * strings. This is the resulting set of character when the character
 * associated with a 16-bit string type is merged with a permitted alphabet
 * constraint.
 *
 * @param pctxt       Pointer to a context structure.
 * @param pCharSet     Pointer to a character set structure describing the
 *                       character set currently associated with the character
 *                       string type. The resulting character set structure
 *                       after being merged with the permSet parameter.
 * @param pAlphabet    Pointer to a structure describing the 32-bit permitted
 *                       alphabet.
 */
EXTERNPER void pu_set32BitCharSet 
(OSCTXT* pctxt, Asn132BitCharSet* pCharSet, Asn132BitCharSet* pAlphabet);

/**
 * @param pCharSet     Pointer to a character set structure describing the
 *                       character set currently associated with the character
 *                       string type. The resulting character set structure
 *                       after being merged with the permSet parameter.
 * @param firstChar    The first character in the range.
 * @param lastChar     The last character in the range.
 */
EXTERNPER void pu_set32BitCharSetFromRange 
(Asn132BitCharSet* pCharSet, OSUINT32 firstChar, OSUINT32 lastChar);

/**
 * Returns numeric version of run-time library. The format of version is as
 * follows: MmP, where:
 *     M - major version number;
 *     m - minor version number;
 *     p - patch release number.
 * For example, the value 581 means the version 5.81.
 * @return             Version of run-time library in numeric format.
 */
EXTERNPER int pu_GetLibVersion ();

/**
 * Returns information string describing the library. The string
 * contains name of library, its version and flags used for building
 * the library.
 *
 * @return     Information string
 */
EXTERNPER const char* pu_GetLibInfo ();

/**
 * @} perutil
 */

#ifdef __cplusplus
}
#endif

/* Macros */

#define pe_GeneralString(pctxt,value,permCharSet) \
pe_VarWidthCharString(pctxt, value)

#define pe_GraphicString(pctxt,value,permCharSet) \
pe_VarWidthCharString(pctxt, value)

#define pe_T61String(pctxt,value,permCharSet) \
pe_VarWidthCharString(pctxt, value)

#define pe_TeletexString(pctxt,value,permCharSet) \
pe_VarWidthCharString(pctxt, value)

#define pe_VideotexString(pctxt,value,permCharSet) \
pe_VarWidthCharString(pctxt, value)

#define pe_ObjectDescriptor(pctxt,value,permCharSet) \
pe_VarWidthCharString(pctxt, value)

#define pe_UTF8String(pctxt,value,permCharSet) \
pe_VarWidthCharString(pctxt, value)

	
#define pe_IA5String(pctxt,value,permCharSet) \
pe_ConstrainedStringEx (pctxt, value, permCharSet, 8, 7, 7)

#define pe_NumericString(pctxt,value,permCharSet) \
pe_ConstrainedStringEx (pctxt, value, \
(permCharSet == 0)?NUM_CANSET:permCharSet, 4, 4, 4)

#define pe_PrintableString(pctxt,value,permCharSet) \
pe_ConstrainedStringEx (pctxt, value, permCharSet, 8, 7, 7)

#define pe_VisibleString(pctxt,value,permCharSet) \

#define pe_ISO646String      pe_IA5String
#define pe_GeneralizedTime   pe_IA5String
#define pe_UTCTime           pe_GeneralizedTime


#define pd_GeneralString(pctxt,pvalue,permCharSet) \
pd_VarWidthCharString (pctxt, pvalue)

#define pd_GraphicString(pctxt,pvalue,permCharSet) \
pd_VarWidthCharString (pctxt, pvalue)

#define pd_VideotexString(pctxt,pvalue,permCharSet) \
pd_VarWidthCharString (pctxt, pvalue)

#define pd_TeletexString(pctxt,pvalue,permCharSet) \
pd_VarWidthCharString (pctxt, pvalue)

#define pd_T61String(pctxt,pvalue,permCharSet) \
pd_VarWidthCharString (pctxt, pvalue)

#define pd_ObjectDescriptor(pctxt,pvalue,permCharSet) \
pd_VarWidthCharString (pctxt, pvalue)

#define pd_UTF8String(pctxt,pvalue,permCharSet) \
pd_VarWidthCharString (pctxt, pvalue)


#define pd_IA5String(pctxt,pvalue,permCharSet) \
pd_ConstrainedStringEx (pctxt, pvalue, permCharSet, 8, 7, 7)

#define pd_NumericString(pctxt,pvalue,permCharSet) \
pd_ConstrainedStringEx (pctxt, pvalue, \
(permCharSet == 0)?NUM_CANSET:permCharSet, 4, 4, 4)

#define pd_PrintableString(pctxt,pvalue,permCharSet) \
pd_ConstrainedStringEx (pctxt, pvalue, permCharSet, 8, 7, 7)

#define pd_VisibleString(pctxt,pvalue,permCharSet) \
pd_ConstrainedStringEx (pctxt, pvalue, permCharSet, 8, 7, 7)


#define pd_ISO646String      pd_IA5String
#define pd_GeneralizedTime   pd_IA5String
#define pd_UTCTime           pd_GeneralizedTime

#define pe_GetMsgLen         pu_getMsgLen

/** @} perruntime */

#endif
