TOP

ASN.1/C Runtime Functions Reference

Applies to: ASN.1/C v11.3

Core Functions

This section describes the basic set of functions used to encode and decode ASN.1 messages. You will learn how to initialize or terminate an encoder or decoder, how to use set or get flags that control the behavior of the encoder or decoder, and how to debug and trace errors.

int ossinit(OssGlobal *world, void *ctl_tbl);
int ossUinit(OssGlobal *world, void *ctl_tbl, char *dllName);
int ossWinit(OssGlobal *world, void *ctl_tbl, char *dllName, HWND hWnd);

These functions initialize an instance of the OssGlobal variable and the compiler-generated control table or code file used with your application.

ossUinit() and ossWinit() enable you to load a control table or code file compiled as a DLL or as a shared library.

NOTE: Before using other OSS API functions, you must call one of these functions. OssGlobal can be used only once.

Arguments

world
Pointer to the OssGlobal variable.
ctl_tbl
Pointer to the control structure in the generated C file that contains the SOED control table or the TOED code file.
dllName
Pointer to the library file path or name string. Enables you to load a control table or code file compiled as a library (shared library on UNIX-like platforms or a DLL on Windows). In this case, ctl_tbl argument is not used and must be set to NULL.
hWnd
Deprecated. Must be set to NULL or 0.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Remarks

For each control table or code file that your application uses, you must allocate and initialize a separate instance of OssGlobal.

If your application uses multiple simultaneous threads, you must keep separate instances of OssGlobal per each thread. To duplicate an instance of OssGlobal for each thread, use ossDupWorld(). Compared to ossinit(), ossDupWorld() has a lower overhead.

See Also

ossterm() | ossUterm() | ossWterm()


void ossterm(OssGlobal *world);
void ossUterm(OssGlobal *world);
void ossWterm(OssGlobal *world);

These functions are used in conjunction with ossinit(), ossUinit(), and ossWinit() after initialization is complete.

In general, when calling these functions, consider the following rules:

  • For ossinit(), use ossterm().
  • For ossUinit(), use ossUterm().
  • For ossWinit(), use ossWterm().

You must also call ossWterm() instead of ossterm() when you use OSS DLLs in your application; ossWterm() frees the OSS DLLs.

Arguments

world
Pointer to the OssGlobal variable.

Return Value

No value is returned.

Remarks

In case you have multiple instances of the OssGlobal variable, you must free each instance separately.

See Also

ossinit() | ossUinit() | ossWinit()


int ossDecode(OssGlobal *world, int *pduid, OssBuf *input, void **output);

Decodes a message contained in a buffer of type OssBuf using one of the available encoding rules. The ossDecode() function fills a specified compiler-generated structure (PDU) with values by decoding the input encoding of a similar structure (PDU).

Arguments

world
Pointer to the OssGlobal variable.
pduid
Pointer to the compiler-assigned PDU ID for the compiler-generated data structure used for decoding.
input
Address of OssBuf. The value field of OssBuf references the encoding buffer to be decoded. The length field holds the length in bytes of this encoding.
output
Address of a pointer to the memory block designated to hold the decoded PDU structure. When set to NULL, the decoder's memory manager automatically allocates memory to hold the decoded data.

You can preallocate a buffer for the decoded data, and pass the address of the pointer that references your preallocated buffer. In this case, the decoder writes the decoded PDU to your provided buffer. However, after preallocating an output buffer, before calling the decoder each time, you must call the ossSetDecodingLength() function to set the length of the allocated buffer.

After a successful return, the decoded data is accessible through the pointer output. If you preallocated a buffer for the decoded data, the resulting PDU structure can be located anywhere, in any number of pieces, within the buffer. The ossDecode() function is not required to start the structure at the beginning of the buffer and finish it in a single piece. Typically, the opposite is true, with pointers providing the location of each subsequent piece. However, the structure is created just as the .h file defines it.

To retrieve the number of bytes occupied by the decoded data, call ossGetDecodingLength(). If a decoding error occurs and the decoding buffer is preallocated, the contents are unpredictable and should not be used. If you set output to NULL, the decoder frees any temporary memory allocated before exit.

Although it's not recommended for everyone, you might consider partial decoding if you are interested in the contents of only a few fields. Rather than call ossDecode(), which would have decoded the entire PDU, you could instead call ossPartialDecode() to decode only those fields you flag with the OSS.DataCallback directive. For details, see the Partial Decoding section.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w, *world = &w;
OssBuf encodedData; /* length and address of encoded data */
DataPacket *DecodedDataPtr = NULL; /* address of decoded data */
int pdu_num;
. . . 
pdu_num = DataPacket_PDU;
if (ossDecode(world, &pdu_num, &encodedData, (void **)&DecodedDataPtr))
{
ossPrint(world, "%s\n", ossGetErrMsg(world)); /* print error message*/
ossterm(world);
retcode = 1;
}
else
{ /* Print out the data that was just decoded. */
ossPrint(world, "\nData decoded to:\n\n"); /* successfully decoded */
ossPrintPDU(world, pdu_num, DecodedDataPtr);
ossFreePDU(world, pdu_num, DecodedDataPtr); /* free up PDU */
retcode = 0;
}

Remarks

To make sure the decoder fills in the correct compiler-generated structure, we recommend that you always pass the PDU number of the data type used for decoding.

In general, when you decode BER, DER, XER, E-XER, or OER messages, the decoder knows which compiler-generated structure to fill in. In this case, you can set the PDU number variable to a value of zero before calling the decoder:

int myPduNum;
  . . . .

myPduNum = 0;
ossDecode(world, &myPduNum, &encodedData, &decodedDataPtr);

Before decoding, the decoder sets the passed PDU number variable equal to the #defined PDU identification constant of the structure filled.

When you decode a message that contains an open type, the decoder will not automatically find its PDU number.

The decoder does not modify the input OssBuf structure. This may cause difficulties in case you decode multiple concatenated PDUs from the same input buffer. To instruct the decoder to set the length field of OssBuf to the number of bytes remaining to be decoded (in the input buffer) and the value field of OssBuf to the beginning of the next encoded PDU, compile your data schema with the -compat decoderUpdatesInputAddress compiler option.

There are three types of encoders: space-optimized, time-optimized, and lean, which share the same interface described above. Each type is contained in its own library file. Therefore, you must explicitly link with the library that contains the type of encoder used. Also, compile your ASN.1 data with the appropriate option (-soed, -toed or -soed -lean).

See Also


int ossEncode(OssGlobal *world, int pduid, void *input, OssBuf *output);

Encodes input data structures into a stream of bits using one of the available encoding rules.

Arguments

world
Pointer to the OssGlobal variable.
pduid
Pointer to the compiler-generated PDU ID for the data structure to be encoded.
input
Pointer to the compiler-generated structure containing the data to be encoded.
output
Pointer to the OssBuf designated to contain the complete encoding. When you set the length and value fields of the output OssBuf variable to NULL and 0, respectively, the encoder will automatically allocate the space needed for the output buffer.

Alternatively, if you preallocate a memory buffer, set the value field of OssBuf to reference the beginning of the buffer, and the length field to the length in bytes of the allocated buffer. After a successful return, the value field of the OssBuf variable points to the encoded data, and the length field contains the length in bytes of the encoding.

When you preallocate an output buffer, ossEncode() may change the value field of the OssBuf variable to point to a location within the output buffer. We recommend that you always keep a separate copy of the beginning address of the preallocated buffer, so you can use the same buffer for your next call to ossEncode(). Also, to free up the buffer after using it, a separate copy of this pointer is useful.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w, *world = &w;
OssBuf encodedData; /* length and address of encoded data */
DataPacket myPacket; /* compiler generated structure */
. . . 
encodedData.value = NULL; /* Initialize encoder output buffer */
encodedData.length = 0;

/* Encode the data. Return non-zero for failure. */
if (ossEncode(world, DataPacket_PDU, &myPacket, &encodedData))
{
ossPrint(world, "%s\n", ossGetErrMsg(world)); /* print error msg */
ossterm(world); /* Free up allocated resources */
   return 1;
}

Remarks

By default, the Basic Encoding Rules (BER) are used. To switch to different encoding rules, use ossSetEncodingRules(). To make certain encoding rules available at runtime, compile your ASN.1 specification using specific compiler options (-per for PER encodings, for example).

There are three types of encoders: space-optimized, time-optimized, and lean, which share the same interface described above. Each type is contained in its own library file. Therefore, you must explicitly link with the library that contains the type of encoder used. Also, compile your ASN.1 data with the appropriate option (-soed, -toed or -soed -lean).

See Also


void ossFreeBuf(OssGlobal *world, void *encodedData);

Frees up buffers allocated by ossEncode() and OBJECT IDENTIFIER value conversion functions (ossEncodedOidToDotVal()). The value field of the OssBuf variable points to the allocated memory.

NOTE: If you have preallocated your own memory buffer before calling the encoder, do not use the ossFreeBuf(). Instead, use your own memory freeing routines.

Arguments

world
Pointer to the OssGlobal variable.
encodedData
Pointer to memory containing encoded data (OssBuf.value).

Return Value

No value is returned for this function.

Example

OssGlobal w, *world = &w;
OssBuf yourEncodedData; /* length and address of encoded data */
. . . 
retcode = ossEncode(world, DataPacket_PDU, &myPacket, &yourEncodedData;
. . .
ossFreeBuf(world, yourEncodedData.value);

See Also

ossEncode()


int ossFreePDU(OssGlobal *world, int pduid, void *data);

Frees up memory allocated by the ossDecode() and ossCpyValue() functions.

If you have preallocated the output buffer to the decoder, do not use ossFreePDU().

Arguments

world
Pointer to the OssGlobal variable.
pduid
Pointer to the compiler-generated PDU ID for the data structure used for deallocation.
data
Pointer to the decoded or copied PDU.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w, *world = &w;
OssBuf encodedData; /* length and address of encoded data */
DataPacket *DecodedDataPtr = NULL; /* address of decoded data */
int pdu_num;
. . . 
pdu_num = DataPacket_PDU;
if (ossDecode(world, &pdu_num, &encodedData, (void **)&DecodedDataPtr))
. . .
else
{ /* Print out the data that was just decoded. */
ossPrint(world, "\nData decoded to:\n\n"); /* successfully decoded */
ossPrintPDU(world, pdu_num, DecodedDataPtr);
ossFreePDU(world, pdu_num, DecodedDataPtr); /* free up PDU */
retcode = 0;
}

See Also


int ossOpenTraceFile(OssGlobal *world, char *fileName);
int ossCloseTraceFile(OssGlobal *world);

Opens or closes a plain text file to redirect encoder/decoder trace output from the screen to the file for functions like: ossPrint(), ossPrintPDU(), ossPrintHex(), etc.

If the specified file already exists, it is overwritten. After closing the file, the trace output returns to the screen or trace window.

Arguments

world
Pointer to the OssGlobal variable.
fileName
Pointer to a character string containing the name of the file used by the encoder/decoder to trace information that is written.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduid = MyASN1DataType_PDU;
MyASN1DataType myData;

ossinit(world, asn1data);
/* Turn on trace capabilities */
ossSetFlags(world, ossGetFlags(world) | DEBUGPDU); 
ossOpenTraceFile(world, "trace.out"); 
. . . 
/* Trace to file */
ossPrint(world, "Starting encoder... \n");
ossEncode(world, myPduid, &myData, &encodedData);
ossPrint(world, "Finished encoding PDU id %d. \n", 
myPduid);
. . .
ossCloseTraceFile(world);
ossterm(world);

Remarks

To capture encoder/decoder trace information, before calling the encoder/decoder, set the DEBUGPDU flag via ossSetFlags().

In a multi-threaded environment, you must call ossOpenTraceFile() for each thread. The first function argument must be a pointer to a separate unshared instance of the OssGlobal structure allocated or initialized for the thread. Also, each thread must write to a different file. If the same output file is used for multiple threads, the result is unpredictable and might cause errors.

If ossLoadMemoryManager() is called while writing trace data to a file, ossOpenTraceFile() must be called again to continue writing the output to a trace file.

See Also

ossSetFlags(.., DEBUGPDU)


char *ossDescribeReturnCode(OssGlobal *world, int retcode);

Returns a description string for a numeric code returned by functions in this API. Unlike the ossGetErrMsg() function that works with the ossEncode() and ossDecode() functions, the ossDescribeReturnCode() function can be used in conjunction with any OSS API function.

Arguments

world
Pointer to the OssGlobal variable.
retcode
Numeric code returned by any function of this API.

Return Value

A pointer to a null-terminated string containing description of the given return code. If the return code is invalid or unknown, NULL is returned.

Example

. . . 
if ((retcode = ossinit(world, ctltbl)))
{
/* world failed to be initialized, will use NULL */
#ifndef DLL_LINKAGE
msg = ossDescribeReturnCode(NULL, retcode); 
#endif /* DLL_LINKAGE */
ossPrint(NULL, "ossinit() returned %d:%s", retcode, msg ? msg : "<unknown>");
return retcode;
}
. . .

Remarks

To receive precise error descriptions, pass a non-NULL preinitialized value of world to the function. A NULL world can be passed only for codes returned by ossinit(), because world is not initialized by that function in case of errors.

When using the OSS DLL runtime on Windows, you must pass a non-NULL preinitialized world to the function. Otherwise, the function will return a NULL value.

See Also

ossGetErrMsg()


unsigned long ossGetAVNFlags(OssGlobal *world);
int ossSetAVNFlags(OssGlobal *world, unsigned long flags);

The ossGetAVNFlags() function returns the AVN-specific flags set by the ossSetAVNFlags() function.

The ossSetAVNFlags() function controls the behavior of the TOED AVN encoder/decoder.

Arguments

world
Pointer to the OssGlobal variable.
flags
One or more of the following literals separated by vertical bars ("|"):
  • AVN_DECODE_CONTAINED_IN_HEX
  • AVN_PRESERVE_INCOMPLETE_VALUE_NOTATION

Here is a detailed description of the flags:

Flag Description
AVN_DECODE_CONTAINED_IN_HEX
Instructs the AVN decoder to automatically decode the containing type from a value of a BIT STRING or OCTET STRING type constrained by contents constraints when the value is provided in the hexadecimal form. When the flag is not specified, the decoder leaves the container OCTET STRING or BIT STRING value in the "encoded" field of the C-representation. The flag has no effect unless the code generated by the ASN.1 compiler is C-compiled using the -DOSS_AVN_DECODE_CONTAINED_IN_HEX option.
AVN_PRESERVE_INCOMPLETE_VALUE_NOTATION
Instructs the AVN encoder not to free the automatically allocated output buffer and to leave in it the incomplete value notation encoding when the ossEncode() function failed with an error. This can be useful for determining the location of an error. Note that it is the user responsibility to free the buffer by ossFreeMemory() API function. By default, the dynamically allocated buffer is automatically freed after an error.

Example

In the following example, the ossGetAVNFlags() function is used:

OssGlobal w, *world = &w;
unsigned long flags;
. . . . 
flags = ossGetAVNFlags(world);
if (flags & AVN_DECODE_CONTAINED_IN_HEX)
           ossPrint(world, " Auto decoding containing type from HEX is set\n");

In the following example, the ossSetAVNFlags() function is used:

OssGlobal w, *world = &w;
void *decoded = NULL, *decoded_hex = NULL;;
unsigned char   avn_enc[] = "value CO ::= '0201 80'H";
OssBuf input;
int rc, rc_hex, pdu = CO_PDU;
...
ossSetFlags(world, NOCONSTRAIN | AUTOMATIC_ENCDEC);
ossSetEncodingRules(world, OSS_ASN1_VALUE_NOTATION);
/* Set input encoding */
input.value = avn_enc;
input.length = sizeof(avn_enc) - 1;
rc = ossDecode(world, &pdu, &input, &decoded);
ossSetAVNFlags(world, ossGetAVNFlags(world) | AVN_DECODE_CONTAINED_IN_HEX);
rc_hex = ossDecode(world, &pdu, &input, &decoded_hex);
if (!rc) {
   ossPrint(world, "Decoded value without AVN_DECODE_CONTAINED_IN_HEX\n");
    ossPrintPDU(world, CO_PDU, decoded);
}
if (!rc_hex) {
   ossPrint(world, "Decoded value with AVN_DECODE_CONTAINED_IN_HEX\n");
    ossPrintPDU(world, CO_PDU, decoded_hex);
}
...

For the following syntax:

Test DEFINITIONS AUTOMATIC TAGS ::= BEGIN
per OBJECT IDENTIFIER ::=
        {joint-iso-itu-t asn1(1) packed-encoding(3) basic(0) aligned(0)}
    I ::= INTEGER
    CO ::= OCTET STRING (CONTAINING I ENCODED BY per)
END

The output of the sample:

The decoded value without AVN_DECODE_CONTAINED_IN_HEX:

value CO ::= '020180'H

The decoded value with AVN_DECODE_CONTAINED_IN_HEX:

value CO ::=
  CONTAINING
  384

Example

In the following example, the ossGetAVNFlags() function is used:

OssGlobal w, *world = &w;
unsigned long flags;
. . . . 
If (ossGetEncodingRules(world) == OSS_ASN1_VALUE_NOTATION) {
    flags = ossGetAVNFlags(world);
    if (flags & AVN_DECODE_CONTAINED_IN_HEX)
           ossPrint(world, " Auto decoding containing type from HEX is set\n");
}

In the following example, the ossSetAVNFlags() function is used:

OssGlobal w, *world = &w;
...
If (ossGetEncodingRules(world) == OSS_ASN1_VALUE_NOTATION) {
    ossSetAVNFlags(world, ossGetAVNFlags(world) | AVN_DECODE_CONTAINED_IN_HEX);
    rc = ossDecode(world, &pdu, &input, &decoded);
    ...
}

For the following syntax:

Test DEFINITIONS AUTOMATIC TAGS ::= BEGIN
per OBJECT IDENTIFIER ::=
        {joint-iso-itu-t asn1(1) packed-encoding(3) basic(0) aligned(0)}
    I ::= INTEGER
    CO ::= OCTET STRING (CONTAINING I ENCODED BY per)
END

The input encoded value:

value CO ::= '0201 80'H

The decoded value without AVN_DECODE_CONTAINED_IN_HEX:

value CO ::= '020180'H

The decoded value with AVN_DECODE_CONTAINED_IN_HEX:

value CO ::=
  CONTAINING
  384

unsigned long ossGetDebugFlags(OssGlobal *world);
int ossSetDebugFlags(OssGlobal *world, unsigned long flags);

Gets or sets the debugging flags.

Arguments

world
Pointer to the OssGlobal variable.
flags
One or more of the flags described in the following table.

The following table contains the available flags and provides a description of their function:

Flag Description
PRINT_DECODER_INPUT
Prints the input of the decoder upon entry. Binary encodings (BER, PER, or OER) are converted by calling ossPrintHex(); otherwise ossPrintXML() is called to print the input as formatted XML. This flag is not available for input from a file or socket.
PRINT_DECODER_OUTPUT
Prints the output of the decoder right before it exits.
PRINT_DECODING_DETAILS
Prints verbose trace messages during decoding. This flag is not available for TOED and LED libraries.
PRINT_ENCODER_INPUT
Prints the input of the encoder upon entry.
PRINT_ENCODER_OUTPUT
Prints the output of the encoder right before it exits. For binary encodings (BER, PER, or OER), ossPrintHex() is called; otherwise ossPrintXML() is called to print the input as formatted XML. This flag is not available for output written to a file or socket.
PRINT_ENCODING_DETAILS
Prints verbose trace messages during encoding. This flag is not available for TOED and LED libraries.
PRINT_ERROR_MESSAGES
Prints error messages using appropriate functions (ossEncode(), ossDecode(), for example) when errors occur.
PRINT_HEX_WITH_ASCII
Instructs ossPrintHex() to print ASCII representations formatted as follows:
# 000000: 4200 7368 6972 7423 DC74 726F 7573 6572 B.shirt#.trouser
# 000010: 73A5 1073 686F 6573 C648 7469 6502 9073 s..shoes.Htie..s
OSS_DEBUG_LEVEL_0
The encoder/decoder will not print diagnostics. This is the default level.
OSS_DEBUG_LEVEL_1
Prints error messages using appropriate functions (ossEncode(), ossDecode()) when errors occur.
OSS_DEBUG_LEVEL_2
Similar to OSS_DEBUG_LEVEL_1. Additionally, prints the input to ossEncode() upon entry, and the output from ossDecode() before exit.
OSS_DEBUG_LEVEL_3
Similar to OSS_DEBUG_LEVEL_2. Additionally, prints the output from ossEncode() before exit, and the input to ossDecode() upon entry.
OSS_DEBUG_LEVEL_4
Similar to OSS_DEBUG_LEVEL_3. Additionally, instructs the encoder and decoder to print verbose trace messages. This flag is not available for TOED and LED libraries. For binary encodings (BER, PER, or OER), ASCII representations of the encoder output and the decoder input are generated.

Return Value

If successful, ossGetDebugFlags() returns all debugging flags set. Otherwise, if world is NUL, it returns -1 (unsigned long). If no prior call has been made to ossSetDebugFlags(), a value of zero is returned.

If the call succeeded, ossSetDebugFlags() returns a value of zero. Otherwise, a non-zero value is returned.

Example

OssGlobal w, *world = &w;
unsigned long flags;
ossSetDebugFlags(world, PRINT_DECODER_INPUT | PRINT_HEX_WITH_ASCII); 
  ...
flags = ossGetDebugFlags(world);
if (flags & PRINT_HEX_WITH_ASCII)
ossPrint(world, "Detailed HEX/ASCII dump:\n");
else
ossPrint(world, "Plain HEX dump:\n");

Remarks

To include debugging capabilities in TOED, define -DOSSPRINT and -DOSSDEBUG=x (x is 1 or greater) while compiling the generated TOED code.

See Also


unsigned long ossGetFlags(OssGlobal *world);
               int ossSetFlags(OssGlobal *world, unsigned long flags);
unsigned long ossGetDecodingFlags(OssGlobal *world);
                int ossSetDecodingFlags(OssGlobal *world, unsigned long flags);
unsigned long ossGetEncodingFlags(OssGlobal *world);
                int ossSetEncodingFlags(OssGlobal *world, unsigned long flags);

Sets or gets the behavior of the encoder or decoder library using the flags described in the table below.

When using these flags, consider the following rules:

  • Use ossSetFlags() | ossGetFlags() with any flag (marked with E, D or O).
  • Use ossSetEncodingFlags() | ossGetEncodingFlags() only with flags marked with (E). These functions affect only the encoder.
  • Use ossSetDecodingFlags() | ossSetDecodingFlags() only with flags marked with (D). These functions affect only the decoder.

For flags shared by both the encoder and decoder (E/D), you can call ossSetFlags() or ossSetEncodingFlags() and ossSetDecodingFlags() functions one after the other.

ossGetFlags() returns the logical OR of all the flags set by ossSetFlags(), ossSetEncodingFlags(), or ossSetDecodingFlags().

Arguments

world
Pointer to the OssGlobal variable.
flags
One or more of the following flags.

The following table contains the available flags and provides a description of their function (E/D/O indicates that the flag applies to the Encoder, Decoder, or Other):

Flag Description
AUTOMATIC_ENCDEC (E/D)
Specifies the automatic encoding and decoding of open types and their containing structures. By default, the encoder or decoder does not handle open types automatically.
BACK_ALIGN (E)
Instructs the encoder to right-justify data within your preallocated output buffer. In most cases, the encoder also modifies the argument output->value. To be able to later free the output buffer, save a copy of it before you call ossEncode().
COMPACT_XER_ENCODING (E)
Available for XER encodings. Removes white space and new line symbols from the resulting XER encoding.
DEBUG_ERRORS (D)
Prints a diagnostic message upon encountering an error, before attempting to continue decoding. The printed diagnostic message is the first one returned by ossDecode(), regardless of the number of errors.
DEBUGPDU (E/D)
Traces data while each PDU is encoded/decoded. Prints a diagnostic message upon encountering an error, before attempting to continue decoding (DEBUG_ERRORS is implied). The printed diagnostic message is the first one returned by ossDecode(), regardless of the number of errors.
DEFAULT_ALIGN (E)
Instructs the encoder to use the most efficient alignment in your preallocated output buffer. The data is left-justified if the Packed Encoding Rules, XML Encoding Rules, or Octet Encoding Rules are in use, or if the BER indefinite length form is in use. Otherwise, data is right-justified. In most cases, the encoder also modifies the argument output->value. To be able to later free the output buffer, save a copy of it before you call ossEncode().
DEFINITE (E)
Available for BER and DER. Instructs the encoder to use the definite length form when encoding.
DETERMINE_ENC_LENGTH (E)
Instructs the encoder (and related functions) to generate the total length of an encoding. Recommended when a custom memory manager is used with the ossEncode() function.

NOTE: This flag is deprecated. Use the ossDetermineEncodingLength() API function instead.
DONT_DO_DECODED / DONT_DO_ENCODED (O)
ossCmpValue() and ossCpyValue() will not compare or copy the decoded / encoded fields of sent open type structures. Recommended when working with open types.
DONT_FREE_ENCODED (D)
The decoder will not free memory allocated for the encoded field of an open type when automatically decoding open types. Memory is usually allocated for the enclosed open type encoding in the outermost call to the decoder.
DONT_OPTIMIZE_XMLNS (E/D)
During decoding: instructs the E-XER decoder to optimize an xmlns declaration generation for decoded values of types with the ANY-ELEMENT instruction, and for open types. By default, when the flag is disabled, the decoder tries to determine the minimum necessary set of namespace prefixes to include their namespace declarations in the outermost part of the decoded abstract value; otherwise, the decoder includes all namespace declarations that are in scope for the element being decoded. Available for LED and TOED.

During encoding: instructs the encoder to produce declarations for all the namespaces referenced in the input ASN.1 schema into the outermost tag of the generated Extended XER encoding. When this flag is disabled, the encoder declares only namespaces referenced by the PDU to be encoded. Thus you will have a cleaner and less verbose XML, but may slow down the encoder by 5-7% (in certain cases) because it requires an extra recursive pass through the value to be encoded.
EXER_ENCODING_OF_DEFAULT_VALUES_AS_COMMENTS (E)
Instructs the E-XER encoder to encode absent DEFAULT fields as XML comments that contain the corresponding default values.
FRONT_ALIGN (E)
Instructs the encoder to left-justify data within the preallocated output buffer.
IGNORE_DEFER_DECODING  (E/D)
Instructs the encoder/decoder to encode/decode open types generated when applying the ASN1.DeferDecoding directive with its containing type. The generated open types can be automatically encoded/decoded if this flag is set, when AUTOMATIC_ENCDEC is also specified. To enable support for this runtime flag in TOED, you must compile TOED generated code file with the IGNORE_DEFER_DECODING_SUPPORTED macro.
IGNORE_PDU_TAG (D)
The decoder will not issue a PDU tag mismatch error message when performing the second decoding on an open type marked for deferred decoding.
INDEFINITE (E)
Available for the space-optimized BER encoder. Instructs the encoder to use the indefinite length form when encoding.
NOCONSTRAIN (E/D)
The encoder/decoder will not perform strict constraint checking, thus improving CPU performance. Not recommended during development for verifying whether your data satisfies all ASN.1 subtype constraints, and if all enumeration values presented for encoding are valid. If the -noConstraints compiler option is specified during ASN.1-compiling of your schema, this flag is ignored.
NOTRAPPING (E/D)
Similar to OSS_TRAPPING, it disables signal trapping. Starting with the 8.2.0 version, it is the default flag. For earlier versions, the default behavior of the encoder/decoder is to trap signals. This helps at identifying errors such as passing bad pointers to encoder/decoder API, and to allow the library to return an error instead of crashing. The downside of signal trapping is that it might affect performance, and it is not always thread-safe. We recommend that you disable trapping for multi-threaded applications built with versions older than 8.2.0.
NO_XML_DECLARATION (E)
Specified for XER encodings. The encoder will not generate XML header declarations (<?xml version="1.0" encoding="UTF-8"?>) at the beginning of subsequently produced XER encodings (default behavior).
OLD_STRICT_ENCODING_DECODING_RULES (D)
Starting with version 10.6, the STRICT_ENCODING_DECODING_RULES flag enforces stricter checking of conformance to encoding rules. For compatibility with pre-10.6 runtimes, use the OLD_STRICT_ENCODING_DECODING_RULES flag, which enforces the same level of conformance checking that was provided by the STRICT_ENCODING_DECODING_RULES flag in previous versions. Both flags override the OSS_RELAXED (RELAXBER, RELAXPER) flag. To correctly set the OLD_STRICT_ENCODING_DECODING_RULES flag, use the following statement:
ossSet...Flags(world, (ossGet...Flags(world) & ~STRICT_ENCODING_DECODING_RULES) | OLD_STRICT_ENCODING_DECODING_RULES);
OSS_AUTO_ENCODE_WITHOUT_CHECKING
_CONSTRAINT (E)
Disables constraint checking for values of types constrained by a component relation constraint. The value must not be present in the referred ObjectSet even when ObjectSet is extensible.
OSS_SKIP_UNKNOWN_CONTENT (D)
Instructs the E-XER decoder to silently discard any unknown elements and attributes in the input (decoded) XML message. This flag takes precedence over the -relaySafe compiler option, meaning that unknown extensions are not saved if the flag is set.
OSS_RELAXED (RELAXBER, RELAXPER) (D/O)
The decoder will not report an error if the input encoding slightly deviates from the ITU-T standards (the Canonical-PER decoder ignores the flag). The admissible deviations are listed below, grouped by encoding rules:

For BER encodings:
  • INTEGER encodings. For example:
    I ::= INTEGER (0..MAX)
    The following encoding is passed to the BER decoder:
    02 03 80 00 7b
    The decoder issues an error message compliant with the ITU-T Standards: a negative unsigned INTEGER was encountered. With the OSS_RELAXED flag:
    02 04 00 80 00 7b
    When the first 9 bits of the encoding are either 1 or 0:
    02 03 00 00 7b,
    The decoder issues an error message compliant with the ITU-T Standards: the INTEGER value encoding is unnecessary long. With the OSS_RELAXED flag, the error is suppressed.
  • BIT STRING encodings that omit the leading octet, which indicate how non-significant trailing bits are in the encoding.
  • BIT STRING encodings that are fragmented, but each fragment contains empty octets.
  • HUGE INTEGER encodings, if the first 9 bits of the encoding are 0.
  • Tag encodings that are too long. For example, an encoding that violates X.690 Clause 8.1.2.2: "For tags with a number ranging from zero to 30 (inclusive), the identifier octets shall comprise a single octet".
  • An encoded object identified with a zero length.
For PER encodings:
  • Length determinant. For example:
    Foo1 ::= VisibleString
    can have the following standard and valid PER ALIGNED encoding:
    04 6E6E6E6E
    The first octet ("04") defines a length of the contents (four octets long). Some applications might incorrectly encode the length field and the value of the length can still be retrieved, but the format of the length field is non-standard. For example:
    8004 6E6E6E6E
    Normally, the PER decoder issues an error message, because the length determinant is encoded using too many octets. A two octet length should be used only when the length is larger than 127, according to the ASN.1 standard. The OSS_RELAXED flag instructs the decoder to retrieve the correct value of the length field while ignoring its incorrect format. Similarly, for extension additions, the decoder accepts an encoded length in the incorrect format.
  • INTEGER encodings that contain unnecessary zero octets.
  • REAL values with the mantissa or exponent encoded in a longer format than required.
  • An encoded object identifier with a zero length.
For E-XER encodings:
  • XML document in UTF-8 encoding, even if the encoding specified by the XML declaration differs from UTF 8 and US-ASCII. For example, <?xml version="1.0" encoding="ISO-8859-1"?><A/>
For all encodings:
  • The decoder will not report an error and decode the special REAL values NaN and MINUS-ZERO as regular zero values on a platform where these special values are not supported. The flag allows zero encoded object identifiers for BER/PER decoders.
  • For SOED, this flag affects the behavior of ossAddInfoObject() when the function adds an object to an Object Set of a class with more than one field marked as UNIQUE. It instructs the function to work in pre-8.5 compatibility mode, namely, to check only the first UNIQUE field in the class for a violation of UNIQUE. For example:
ERROR-CLASS ::= CLASS {
  &code OBJECT IDENTIFIER --<ENCODED|OBJECTID 100>-- UNIQUE,
  &category PrintableString (SIZE(1)) UNIQUE,
  &Type
} WITH SYNTAX {&code &category &Type} 
OSS_TRAPPING (E/D)
Enables signal trapping. Starting with 8.2.0 version, it is disabled by default. Signal trapping helps at identifying errors such as passing bad pointers to encoder/decoder API, and allows the library to return an error instead of crashing. The downside is that it might affect performance, and it is not always thread-safe. We recommend that you disable trapping for multi-threaded applications built with versions older than 8.2.0. The NOTRAPPING flag is supported for compatibility, but OSS_TRAPPING takes precedence.
RELAY_OPEN_TYPE_IN_HEX  (E)
Used with XER encoders. Values of open types that cannot be represented as valid XML can be encoded as their hexadecimal equivalent. This ensures that the binary encoding (BER, PER, etc.) can be re-encoded into XER and relayed if it contains undecoded BER or PER open type values. If this flag is not set, the encoder does not validate the contents of pre-encoded open types and places them in binary (assuming it is XML). If this flag is set, the encoder checks that the contents are well formed and places "well-formed" contents into binary (XML). Contents that are not well-formed are placed in HEX.
Note that this flag may affect performance. The HEX contents cannot be used:
  • In CXER mode.
  • In conjunction with automatic decoding (AUTOMATIC_ENCDEC flag is ignored by the decoder when an HEX encoded Open Type is found.
  • In conjunction with OSS.NOCOPY and OSS.DeferDecoding compiler directives.
STRICT_CONSTRAINT_CHECKING (E/O)
Enables the following:
  • Strict constraint checking by the ossCheckConstraints() API function for table and component relation constraints when there is an extensible object set. The constraints are checked as if the object set is not extensible. Regardless of the actual value of the flag, the encoder checks table and component relation constraints as if the flag were set, unless the OSS_AUTO_ENCODE_WITHOUT_CHECKING_CONSTRAINT flag is set.
  • Strict constraint checking in the Space-Optimized encoder and the ossCheckConstraints() API function to make sure the input value falls within all bounds of an extensible constraint. This flag does not affect the behavior of the other encoders/decoders (LED) unless the Space Optimized libraries are also linked in.
  • If this flag is passed to the encoder or to the constraint checker, the extension markers "..." of enumerations, of value ranges, and of size constraints are ignored (while checking constraints). In other words, only the enumeration root or the additional enumeration (extension root and the extension additions of constraints) are used to check the value's validity. For example:
    A ::= INTEGER (1..2, ...)
    B ::= SEQUENCE (SIZE(1..2, ...)) OF INTEGER
    C ::= INTEGER (1..2, ..., 3..4)
    D ::= SEQUENCE (SIZE(1..2, ..., 3..4)) OF INTEGER
    E ::= ENUMERATED {zero(0), one(1), ..., three(3)}
    The results of constraint checking when the flag is set are the following:
    v0 A ::= 1           -- valid (extension root)
    v1 A ::= 3           -- invalid (unknown extension)
    v2 B ::= { 1, 2, 3 } -- invalid (unknown SIZE extension)
    v3 C ::= 3           -- valid (extension addition)
    v4 D ::= { 1, 2, 3 } -- valid (SIZE extension addition)
     -- values of the extensible enumerated type E
    0 - valid (root enumeration)
    1 - valid (root enumeration)
    2 - invalid (unknown enumeration)
    3 - valid (additional enumeration)
    4 - invalid (unknown enumeration)
    If the flag is not passed, all the above values are considered valid.
STRICT_ENCODING_DECODING_RULES (E/D)
Enables strict checking of conformance to encoding rules. The flag overrides the OSS_RELAXED (RELAXBER, RELAXPER) flag. When the flag is set, the following are not allowed by the decoder:
  • Zero length extensions.
  • Extension addition bit-map fields with a zero length or all bits set to zero.
  • Incorrect fragmentation of PER encoding. For more information, refer to Clause 11.9.3.8.1 of X.691.
  • Zero length BIT STRING BER encodings for the SOED decoder. This is the default behavior for the TOED and LEAN decoders.
  • Non-zero padding bits in PER Aligned (Canonical PER Aligned) encodings for SOED and LEAN decoders; non-zero padding bits are not allowed in OER, COER, and JSON encodings for the TOED decoder.
  • Additional unknown extensions after receiving any root components which follow the extension insertion point of a SEQUENCE type for SOED and LEAN BER decoders. For TOED BER decoder, receipt of such extensions will result in a length inconsistency error.
  • Extension bit "1" followed by a value belonging to the extension root or extension bit "0", followed by an extension value for the SOED and LEAN decoders.
  • Inadmissible tags of extensible CHOICE fields. For more information, refer to Clause 29.7 of X.680.
  • Zero length values of OpenType and ANY are not allowed. If automatic decoding is turned on, then zero length values of OpenType are not allowed, regardless of the flag.
Starting with version 10.6, the flag enables the following additional checks for the PER decoder. Note that the last two items of the list also apply to all encoders. To restore the pre-10.6 runtime behavior, use the OLD_STRICT_ENCODING_DECODING_RULES flag instead of STRICT_ENCODING_DECODING_RULES.
  • Encodings of REAL types are checked for full compliance with the requirements of the ISO 6093 NR3 form:
    • SPACE must not be used within the encoding.
    • If the real value is negative, then it must begin with a MINUS SIGN ("-"), otherwise, it must begin with a digit.
    • Neither the first nor the last digit of the mantissa can be a 0.
    • The last digit in the mantissa must be immediately followed by FULL STOP ("."), followed by the exponent-mark "E".
    • If the exponent has the value 0, it must be written "+0", otherwise the exponent's first digit must not be zero, and the PLUS SIGN must not be used.
  • Length determinants, choice indexes, etc. that should be encoded as a "normally small number" are checked to ensure they are indeed encoded in this way.
  • Bit-map extension is checked to ensure it contains at least one non-zero bit if the extension bit is '1'.
  • The value is checked to ensure it is not within the range of the extension root if the extension bit is '1'.
  • The length is checked to ensure it is not within the range of the extension root if the extension bit is '1'.
  • Encodings of GeneralizedTime/UTCTime types with a null-terminated representation are checked for compliance with X.680 Clause 46/47 .
  • Encodings of OBJECT IDENTIFIER types are checked for an excessive number of octets, that is, the leading octet of subidentifiers must not be "0x80".
  • UTF-8 strings are checked for byte sequence validity. The high and low surrogate halves used by UTF-16 (U+D800 through U+DFFF) and code points that are not encodable by UTF-16 (those following U+10FFFF) are considered illegal Unicode values and their UTF-8 encoding is treated as an invalid byte sequence. The 0xfffe and 0xffff octets are also treated as an invalid byte sequence. also See the OSS_OLD_UTF8_CHECK runtime compatibility flag.
STRICT_PER_ENCODING_OF_DEFAULT_VALUES (E)
The PER encoder will not encode components defined with a DEFAULT value when the value to be encoded matches the DEFAULT. To enable support for this runtime flag in TOED, compile the TOED generated code file with the OSS_STRICT_PER_ENCODING_OF_DEFAULT_VALUES macro.
USE_COMPRESSION (E/D)
Instructs the decoder to decompress or decrypt the encoded data using the preset decompression or decryption routine before returning the decoded data. The user must ensure that the same algorithm is used by the decoder for decompression or decryption as it was used by the encoder for compression or encryption. When no valid compression or encryption function is set, the encoder will return the BAD_ARG error code.

Return Value

For ossSet...Flags(): If successful, it returns zero. Otherwise, it returns a non-zero value.

For ossGet...Flags(): If successful, it returns all the effective flags in place. If world is found NULL, it returns -1. If no prior call has been made to either ossSetFlags(), ossSetEncodingFlags(), or ossSetDecodingFlags(), it returns zero.

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduid = MyASN1DataType_PDU;
MMyASN1DataType myData, *DecodedDataPtr;
. . . 
ossSetFlags(world, ossGetFlags(world) | BACK_ALIGN);
ossEncode(world, myPduid, &myData, &encodedData);
. . .
ossSetDecodingFlags(world, 
ossGetDecodingFlags(world) | OSS_RELAXED | DEBUGPDU | OSS_TRAPPING);
ossDecode(world, &myPduid, &encodedData, (void **)&DecodedDataPtr);

Remarks

Each time you call a "set" function, all previous flags are overwritten. To keep the previous settings, first call "get", then perform a logical OR between the returned value and the new flags you want to set. For example:

&ossSetFlags(world, ossGetFlags(world) | OSS_RELAXED);

See Also


unsigned long ossGetJsonFlags(OssGlobal *world);
int ossSetJsonFlags(OssGlobal *world, unsigned long flags);

The ossGetJsonFlags() function returns the JSON-specific flags set by the ossSetJsonFlags() function.

The ossSetJsonFlags() function controls the behavior of the JSON encoder.

Arguments

world
Pointer to the OssGlobal variable.
flags
One or more of the following literals separated by vertical bars ('|'):
  • JSON_ENC_ABSENT_COMPONENTS
  • JSON_ENC_DEFAULT_VALUES
  • JSON_USE_UNICODE_ESCAPE_SEQUENCE
  • JSON_COMPACT_ENCODING
  • JSON_ENC_CONTAINED_AS_TEXT

Here is a detailed description of the flags:

Flag Description
JSON_ENC_ABSENT_COMPONENTS
Instructs the JSON encoder to include the "null" token for absent optional components whose types are not NULL or open types. When the flag is not specified, absent optional components of SET and SEQUENCE types are not encoded.
JSON_ENC_DEFAULT_VALUES
Instructs the JSON encoder to encode absent SET or SEQUENCE type components defined with the DEFAULT syntax either as their default value or as "null" depending on the JSON_ENC_ABSENT_COMPONENTS flag settings. When the JSON_ENC_DEFAULT_VALUES flag is not specified, absent components are not encoded.
JSON_USE_UNICODE_ESCAPE_SEQUENCE
Instructs the encoder to encode each non-ASCII character in restricted character string type values using the "\uxxxx" unicode escape sequence. When the flag is not specified, non-ASCII characters are UTF-8 encoded. For example, when the flag is not specified, the COPYRIGHT SIGN character is UTF-8 encoded into two octets, 0xC2 and 0xA9. When the flag is set, it is encoded using the "\u00A9" unicode escape sequence.
JSON_COMPACT_ENCODING
Instructs the JSON encoder to create a compact JSON encoding with no whitespace and new lines. When the flag is not specified, the encoder inserts whitespace and newlines to improve readability.
JSON_ENC_CONTAINED_AS_TEXT
Instructs the JSON encoder to encode values of BIT STRING or OCTET STRING types with contents constraints as text (the JSON value represents the contained value) rather than hex string.

After a successful return, the specified flags are set to modify the behavior of the encoder starting with its next call.

Return Value

The ossGetJsonFlags() function returns an unsigned long integer. Upon a successful call, the flags set for the encoder are returned. If world is NULL, a value of (unsigned long) -1 is returned. If no prior call was made to the ossSetJsonFlags() function, a value of zero is returned.

The ossSetJsonFlags() function returns an integer. Upon a successful call, a value of zero is returned; otherwise, a non-zero value is returned.

NOTE: By default, (after the ossInit() call) none of the above JSON flags is set.

Example

In the following example, the ossGetJsonFlags() function is used:

OssGlobal w, *world = &w;
unsigned long flags;

. . . . 

flags = ossGetJsonFlags(world);
if (flags & JSON_COMPACT_ENCODING)
           ossPrint(world, "Compact encoding will be created.\n");
else
           ossPrint(world, "Indented encoding will be created.\n");

In the following example, the ossSetJsonFlags() function is used:

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduNum = MyASN1DataType_PDU;
MyASN1DataType myData;

. . . . 

if (ossGetEncodingRules(world) == OSS_JSON)
		ossSetJsonFlags(world, ossGetJsonFlags(world)
|  JSON_ENC_CONTAINED_AS_TEXT);
	ossEncode(world, myPduNum, &myData, &encodedData);

For the following syntax:

A ::= SEQUENCE {
   opaque OCTET STRING (CONTAINING SEQUENCE {
      name UTF8String,
      age INTEGER
   })
}
v A ::= { opaque CONTAINING { name "John", age 33 } }

the OCTET STRING value is encoded as hex string:

{
   "opaque":"7B0A2020226E616D65223A224A6F686E222C0A202022616765223A33330A7D"
}

When the JSON_ENC_CONTAINED_AS_TEXT JSON runtime flag is set, it is encoded in the expanded form:

{
   "opaque":{
       "containing":{
           "name":"John",
           "age":33
       }
   }
}

Version Information

The ossGetJsonFlags() and ossSetJsonFlags() functions are available since version 10.3.


int ossGetJsonIndentSize(OssGlobal *world);
int ossSetJsonIndentSize(OssGlobal *world, int indent_size);

The ossGetJsonIndentSize() function returns the indentation size used by the JSON encoder. By default, the encoder indents two spaces.

The ossSetJsonIndentSize() function sets the indentation size used by the JSON encoder.

Arguments

world
Pointer to the OssGlobal variable.
indent_size
The number of spaces used by the JSON encoder as an indentation size. NOTE: The maximum number of spaces is 256; a negative value enables compact mode.

Return Value

The ossGetJsonIndentSize() function returns an integer value that represents the number of spaces used as an indentation size. If world is NULL, a negative value is returned.

The ossSetJsonIndentSize() function returns an integer. Upon a successful call, a value of zero is returned; otherwise, a non-zero value is returned.

Example

In the following example, the ossGetJsonIndentSize() function is used:

OssGlobal w, *world = &w;
int       iSize;

. . . . 

iSize = ossGetJsonIndentSize(world);
ossPrint(world, "Size of indentation is %d.\n", iSize);

In the following example, the ossSetJsonIndentSize() function is used:

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduNum = MyASN1DataType_PDU;
MyASN1DataType myData;

. . . . 

if (ossGetEncodingRules(world) == OSS_JSON)
	ossSetJsonIndentSize(world, 4);
ossEncode(world, myPduNum, &myData, &encodedData);

Version Information

The ossGetJsonIndentSize() and ossSetJsonIndentSize() functions are available since version 10.3.


int ossGetEncodingRules(OssGlobal *world);
int ossSetEncodingRules(OssGlobal *world, ossEncodingRules rules);

Gets or sets the encoding rules to be used by the encoder and decoder. PDUs are encoded according to the specified rules. The decoder decodes sent encodings according to the specified rules. By default, the Basic Encoding Rules (BER) is used by the encoder or decoder. To change the default mode, use: -cer, -der, -per, -uper, -cper, -cuper, -xer, -cxer, -exer, -oer, -coer, -json, or -avn compiler options when ASN.1-compiling your schema. To switch between multiple encoding rules at runtime, specify multiple compiler options at ASN.1-compile time.

Starting with version 10.1, the Octet Encoding Rules (OER) and Canonical Octet Encoding Rules as specified by ITU-T Recommendation X.696 | ISO/IEC 8825-7: 2015 are also supported. To use these rules with the ossEncode() and ossDecode() functions, compile with the -oer/-coer option specified and set the OSS_OER/OSS_COER flag using the ossSetEncodingRules() function before calling the encoder/decoder.

Arguments

world
Pointer to the OssGlobal variable.
rules
One of the following literals: OSS_BER, OSS_CER, OSS_DER, OSS_PER_ALIGNED, OSS_PER_UNALIGNED, OSS_CPER_ALIGNED, OSS_CPER_UNALIGNED, OSS_XER, OSS_CXER, OSS_EXER, OSS_OER, OSS_COER, OSS_JSON, or OSS_ASN1_VALUE_NOTATION. It identifies the encoding rules that ossEncode() will use in encoding and ossDecode() will use in decoding.

Return Value

For ossSetEncodingRules(): If successful, it returns zero. Otherwise, it returns a non-zero value.

For ossGetEncodingRules(): Returns the currently active rule.

Example

In the following example, the encoder will use the Distinguished Encoding Rules (DER). The control table or code file and header file have been generated with the -ber or -der ASN.1 compiler option.

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduid = MyASN1DataType_PDU;
MyASN1DataType myData;
. . . 
if(ossGetEncodingRules(world) == OSS_DER)
ossPrint(world, "Encoding data using DER");
else
ossSetEncodingRules(world, OSS_DER);
ossEncode(world, myPduid, &myData, &encodedData);

See Also


char *ossGetErrMsg(OssGlobal *world);

Retrieves error messages generated by the OSS functions. Call this function when ossEncode(), ossDecode(), ossConvertData(), ossPrintPER(), ossPrintXPER(), ossCompress(), ossUnCompress(), ossXML2Binary(), or ossBinary2XML() returns a non-zero value or when ossDetermineEncodingLength() returns a zero value.

Arguments

world
Pointer to the OssGlobal variable.

Return Value

If OssGlobal is NULL, it returns NULL. Otherwise, it returns a pointer to a zero-terminated error message string.

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduid = MyASN1DataType_PDU;
MyASN1DataType myData;
. . . 
ossPrint(world, "Starting encoder... \n");
if(ossEncode(world, myPduid, &myData, &encodedData))
ossPrint(world, "%s", ossGetErrMsg(world));

See Also


int ossPrint(OssGlobal *world, const char *format, ...);

Replaces the printf()and fprintf() C functions. The output text is printed to the device that the asn1out field of the OssGlobal structure points to. If world is NULL, the function calls printf().

Arguments

world
Pointer to the OssGlobal variable.
format
Similar to printf().

Return Value

If successful, it returns the number of written bytes. Otherwise, it returns -1.

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduid = MyASN1DataType_PDU;
MyASN1DataType myData;
. . . 
ossPrint(world, "Starting encoder... \n");
ossEncode(world, myPduid, &myData, &encodedData);
ossPrint(world, "Finished encoding PDU id %d. \n", myPduid);

Remarks

On certain platforms, ossPrint() calls fprintf(). To port your code to a platform that has a graphical environment (Windows), and to ensure that data trace works correctly, we recommend that you use ossPrint() instead of fprintf().

See Also


void ossPrintJSON(OssGlobal *world, char *encodedData, long length, ossBoolean pretty_print);

Prints JSON encodings in a well-formatted manner. We recommend that you use this function when printing JSON encodings.

Arguments

world
Pointer to the OssGlobal variable.
encodedData
The value field of the OssBuf structure referencing the input JSON encoding.
length
The length field of the OssBuf structure containing the length in bytes of the JSON encoding.
pretty_print
An ossBoolean variable that determines whether the printed JSON encoding should be formatted to improve readability (a value of TRUE indicates that this type of formatting is used).

The ossSetJsonIndentSize() API function can be used to set a custom indentation size. By default, the encoder indents two spaces.

Upon a successful return, the JSON encoding is printed to the stream pointed to by the asn1out field of the OssGlobal structure.

Return Value

The ossPrintJSON() function does not have a return value.

Example

OssGlobal w, *world = &w;
MyASN1PDU *inputData;
OssBuf encodedData;
. . . . 
ossEncode(world, myPduNum, inputData, &encodedData);
ossPrintJSON(world, encodedData.value, encodedData.length, TRUE);

Version Information

The ossPrintJSON() function is available since version 10.3.

See Also

ossSetJsonIndentSize()


void ossPrintHex(OssGlobal *world, char *encoding, long encodingLength);

Displays BER, DER, PER, UPER, CPER, CUPER, OER, COER, and JSON encodings contained in an OssBuf.value. By default, the output of this function is hexadecimal. When the PRINT_HEX_WITH_ASCII debugging flag is set (see ossSetDebugFlags()), the output includes the ASCII representation for printable characters ("." for unprintable characters).

Arguments

world
Pointer to the OssGlobal variable.
encoding
The value field of an OssBuf variable referencing the encoding.
encodingLength
The length of the encoding (in bytes).

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduid = MyASN1DataType_PDU;
MyASN1DataType myData;
;. . . 
ossPrint(world, "Starting encoder... \n");
ossEncode(world, myPduid, &myData, &encodedData);
ossPrint(world, "Finished encoding PDU id %d. \n", 
myPduid);
ossPrint(world, "\nData encoded to:\n");
ossPrintHex(world, (char*)encodedData.value, encodedData.length); 

A BER encoded IA5String "Hello" yields the following output:

16054865 6C6C6F

With PRINT_HEX_WITH_ASCII enabled:

# 000000: 1605 4865 6C6C 6F ..Hello

Remarks

The output text is printed to the device pointed to by the asn1out field of the OssGlobal structure.

See Also


void ossPrintOctetAsASCII(OssGlobal *world, char* strHex );
void ossPrintOctetAsIPAddress(OssGlobal *world, char* strHex);

These functions convert and print the null-terminated input string, formatted as "'xx...xx'H", into a human readable text or a dotted notation IP-address, respectively.

Each xx represents a single character or an IP octet in HEX form. Non-printable characters are printed as "?". These functions are especially useful with the OSS.PrintFunctionName directive.

Arguments

world
Pointer to the OssGlobal variable.
strHex
References a string formatted as "'xx...xx'H" printed as human readable string.

Example

ossPrintOctetAsASCII() prints the string '4578616D706C65204F7267616E697A6174696F6E'H as follows:

Example Organization

ossPrintOctetAsIPAddress() prints the string '7F000001'H as follows:

127.0.0.1

Remarks

The output text is printed to the stream pointed to by asn1out field of the OssGlobal structure.

See Also

OSS.PrintFunctionName


void ossPrintOctetAsBCDString (OssGlobal *world, char *display);

Prints a stream of octet-aligned data bits as a BCD string. The function was added in version 10.2.0.

Arguments

world
Pointer to the OssGlobal variable.
display
A character string pointer that references the data that is printed as a BCD string.

Return Value

The ossPrintOctetAsBCDString() function does not have a return value.

Remarks

The ossPrintOctetAsBCDString() function is especially useful when used with the OSS.PrintFunctionName directive. For more information, see Compiler Directives.

See Also

ossPrintOctetAsTBCDString()


void ossPrintOctetAsTBCDString(OssGlobal *world, char *display);

Prints a stream of octet-aligned data bits as a TBCD string. The function was added in version 10.2.0.

Arguments

world
Pointer to the OssGlobal variable.
display
A character string pointer that references the data that is printed as a TBCD string.

Return Value

The ossPrintOctetAsTBCDString() function does not have a return value.

Remarks

The ossPrintOctetAsTBCDString() function is especially useful when used with the OSS.PrintFunctionName directive. For more information, see Compiler Directives.

See Also

ossPrintOctetAsBCDString()


void ossPrintOctetAsTimeStamp(OssGlobal *world, char *display);

Converts a null-terminated input string formatted as "'xx...xx'H" into a human-readable timestamp format, YYYYMMDDhhmmss[+-]hhmm, and prints it. Each of the nine input hexadecimal xx pairs except for the seventh are treated as two decimal xx digits. The seventh pair should be a hexadecimal code of either a plus (+) or minus (-) ASCII character. Unexpected hex digits are printed as question marks (?). This function is especially useful with the OSS.PrintFunctionName directive. When the input string length is not 21, the string is printed as is.

Arguments

world
Pointer to the OssGlobal variable.
display
References a string formatted as "'xx...xx'H" that will be converted.

Example

ossPrintOctetAsTimeStamp() prints the string '1507061432002B0600'H as follows:

20150706143200+0600

ossPrintOctetAsTimeStamp() prints the incorrect string 'F5A70B1C32DE2FABCD'H as follows:

???5?70?1?32???????

Remarks

The output text is printed to the stream pointed to by the asn1out field of the OssGlobal structure.

See Also


int ossPrintPDU(OssGlobal *world, int pduid, void *data);

Serializes the content of compiler-generated structures (before encoding or after decoding) into the standardized ASN.1 value notation format, then writes the content to the standard output.

Arguments

world
Pointer to the OssGlobal variable.
pduid
The PDU ID of the compiler-generated data structure to be printed.
data
The address of this data structure.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

MyASN1DataType ::= SEQUENCE {
  field1 IA5String,
  field2 INTEGER
}

C representation:

#define MyASN1DataType_PDU 1
typedef struct MyASN1DataType {
  char *field1;
  int field2;
} MyASN1DataType;

Application code excerpt:

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduid = MyASN1DataType_PDU;
MyASN1DataType myData;
. . . 
myPduid = MyASN1DataType_PDU;
myData.field1 = "Hello";
myData.field2 = strlen(myData.field1); 
ossPrintPDU(world, myPduid, &myData);

ossPrintPDU() output:

value MyASN1DataType ::= 
{
  field1 "Hello",
  field2 5
}

See Also


int DLL_ENTRY ossPrintPDUToBuffer(struct ossGlobal *world, int pduNum, void *data, OssBuf *output);

Allows printing of PDU values in compiler-generated structures into a C-string before encoding or after decoding.

Arguments

world
Pointer to the OssGlobal variable.
pduNum
PDU number for the compiler-generated data structure to print out, data is the address of the data structure for printing, and output is the address of an OssBuf variable designated to contain the print of the PDU.

There are two typical use cases:

  • Printing into a C-string allocated dynamically by the function. In this case, you must initialize the value and length fields of the output OssBuf variable to NULL and 0, respectively. When complete, the output->value field points to the allocated C-string and output->length contains the string length (including a trailing zero octet). Note that even if the function returns a non-zero value, output–>value could contain an incomplete print.
  • Printing into a preallocated memory buffer. In this case, you must initialize the value and length fields of the output OssBuf variable to the beginning of the buffer and the length field to the length in bytes of the allocated buffer. Note that even if the function returns a non-zero value, output->value could contain an incomplete print.

Example

OssGlobal w, *world = &w;
OssBuf outputData;
int myPduNum = MyASN1DataType_PDU;
MyASN1DataType myData;

. . . . 
outputData.length = 0;
outputData.value = NULL;
. . . . 

ossPrintPDUToBuffer(world, myPduNum, &myData, &outputData);
. . . . 

ossFreeBuf(world, outputData.value);

See Also


int ossPrintPER(OssGlobal *world, int *pduid, OssBuf *input, void **output,
                  long flags, UserPrintPer userPrintPer);
int ossPrintXPER(OssGlobal *world, int *pduid, OssBuf *input, void **output,
                  long flags, UserPrintPer userPrintPer);

Decodes and prints a human readable representation of the input PER encoding (aligned or unaligned).

ossPrintXPER() prints in a web-friendly XML format. The human readable representation of PER encoding includes fields names, padding bits, location in the message, and other encoding details. You can specify your own printing and formatting function (via UserPrintPer argument), therefore all the information about the input PER encoding is passed in a generic data structure, allowing you to print them in your custom format. These functions are useful during debugging and for writing protocol analyzers.

ossPrintPER() and ossPrintXPER() are not available for TOED, and must be linked with the SOED library.

NOTE: This utility is not part of the general OSS API but is available separately in its own library file (contact Sales <info@oss.com> for more information). The PER Encoder Analyzer is only available on common platforms like Windows, Linux, and Solaris, and may not be available for your embedded system port. If you are interested in PrintPER for your platform, contact Sales <info@oss.com>.

Arguments

world
Pointer to the OssGlobal variable.
pduid
The PDU ID of the compiler-generated data structure to print.
input
Pointer to OssBuf, where OssBuf.value and OssBuf.length reference the encoding.
output
Similar to the output argument of ossDecode(). In case you need to print and not to decode, set it to NULL.
flags
To specify the default printing behavior or to have one or more configuration flags, set it to 0. If you need to use default print formatting userPrintPer can be set to NULL or can be set to point to your own printing function, which receives the information about the input encoding.

Two flags affect the output of ossPrintXPER():

  • OSS_HEXBYTES
  • OSS_NOPRINT

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value. The non-zero value has the same meaning as the return value of ossDecode().

Example

For a complex PDU specified as:

Foo ::= SEQUENCE {
  a INTEGER (250..253) OPTIONAL,
  ...,
  [[
  b NumericString (SIZE(3)),
  c INTEGER
  ]],
  ...,
  d BOOLEAN OPTIONAL
  }
		
  fooValue Foo ::= { a 253, b "123", c 20000, d TRUE }

When you invoke ossPrintPER() with the OSS_HEXBYTES | OSS_PRINT_ABSREF | OSS_PRINT_OFFSET | OSS_PRINT_TYPE_INFO | OSS_PRINT_COMMENTS flags, the following output is generated:

PER unaligned Encoding:

FC04148D 00938800
value Foo ::=
{
 --TYPE INFORMATION: SEQUENCE
 --OFFSET: 0,0
 --extension flag: <.1>
 --preamble: <11>
 --bit #0 = 1: 'a' is present
 --bit #1 = 1: 'd' is present
 a 253,
 --TYPE INFORMATION: INTEGER (250..253) OPTIONAL
 --FULL NAME: a
 --OFFSET: 0,3; LENGTH: 0,2
 --contents: <11>
 d TRUE,
 --TYPE INFORMATION: BOOLEAN OPTIONAL
 --FULL NAME: d
 --OFFSET: 0,5; LENGTH: 0,1
 --contents: <1>
 --extension preamble size flag: <0> (preamble size <= 64)
 --extension preamble length: <0.00000> (decoded as 1)
 --extension preamble: <1>
 --bit #0 = 1: version brackets that contain:
 --'b'
 --'c'
 --is present
 --[[
 --extension length: <00.000101> (decoded as 5)
 b "123",
 --TYPE INFORMATION: NumericString (SIZE(3))
 --FULL NAME: b
 --OFFSET: 2,6; LENGTH: 1,4
 --contents: <00>.8D.<00>
 c 20000
 --TYPE INFORMATION: INTEGER
 --FULL NAME: c
 --OFFSET: 4,2; LENGTH: 3,0
 --length: <000000.10> (decoded as 2)
 --contents: <010011>.88.<00>
 --trailing bits: <0000>
 --]]
}
--PDU padding: <00>
--TOTAL LENGTH: 8,0

When you specify your own printing or formatting function with userPrintPer, the following structure is passed as a parameter:

struct PrintPerRecord {
unsigned char typeId; /* identifies the present record type */
ossBoolean possibleLast; /* used when typeId = OSS_ASN1_TYPE
TRUE, if there is a chance that this value is the last element of
constructed type */
void *decodedContent; /* decoded contents in "display" format */
char *typeName; /* name of the ASN.1 type */
char *fieldName; /* name of a field */
char *qualifiedName; /* "full" name */
char *qualifiedNameOfTopRecord; /* name of the top level record */
char *qualifiedNumber; /* identifier of the record in a set of records

for example, 1.2.1.3 */
char *qualifiedNumberOfTopRecord; /* identifier of top record; e.g 1.2.1 */
unsigned int depth;
unsigned char *encodedContent; /* encoding of the record */
unsigned char encodedBitOffset; /* the offset of the encoding */
unsigned long length; /* length of encoding (in bits) */
unsigned int numberOfSimplestRecord; /* number of simplestRecords */
struct PrintPerSimplestRecord *simplestRecords; /* array of logical
				parts */
unsigned char bitsPerContentUnit; /* usually - 8, but could differ

for strings with constraints specified */
unsigned int offset; /* offset from a start of encoded data */
ossBoolean allocMem; /* TRUE if decodedContent points to allocated memory */
struct PrintPerRecordAddition *addition;
};

Remarks

By default, ossPrintPER() sends its output to the stream pointed to by the asn1out field of the OssGlobal structure.

The PER Encoder Analyzer comes with a set of default XML stylesheets (.xsl files) to help you display the generated XML output in a user-friendly ASN.1-tuned format.

To use this function, you need a separate library (in addition to the regular encoder/decoder). When you include this functionality into your application, also include osspasn.h and the library file libprintasn.a (on UNIX systems) or printasnmt.lib (on Windows systems) to build successfully.

See Also


int ossTest(OssGlobal *world, int pduid, void *data);

Used for testing a sample PDU by invoking a sequence of operations, including: encoding, decoding, printing, copying, comparing, and freeing.

This function is useful for beginners learning how to use the OSS ASN.1/C Tools, and for advanced users who want to see a particular data structure in encoded and decoded format.

Arguments

world
Pointer to the OssGlobal variable.
pduid
The PDU ID of the compiler-generated data structure to print.
data
Compiler-generated structure containing PDU data.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Remarks

By default, ossTest() prints to the stream pointed to by the asn1out field of the OssGlobal structure.

The -test ASN.1 compiler option is an alternative method of testing the encoding/decoding of your data. When this option is specified, a main() function is produced in the ASN.1 compiler-generated C file. The main() function calls ossTest(). Then, you compile and link the ASN.1-compiler-generated C file, and run the executable. Note that you must define the types and the values (value references) that is tested.


int ossTestPD(OssGlobal *world, int pdunum, void *data);

The ossTestPD() function only becomes available when you use the TOED library and employ either the -enablePartialDecode or -partialDecodeOnly option at ASN.1 compile time.

Arguments

world
Pointer to the OssGlobal variable.
pdunum
Integer type containing the PDU number for the compiler-generated data structure to be encoded and decoded.
data
Address of the value-filled data structure.

Return Value

The ossTestPD() function returns an integer. Upon a successful call, a value of zero is returned; otherwise, the last error code encountered is returned. For more information about the OSS API function error codes, see the ASN.1/C API Return Codes section.

Remarks

Upon a successful return, the passed PDU is encoded and partially decoded. During partial decoding, tracing information about the callback functions calls and the values of the fields to which the DataCallback directive is applied are printed to the stream specified by the asn1out field of the OssGlobal structure.

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
int myPduNum = MyASN1DataType_PDU;
MyASN1DataType myData;
. . . . 
ossTestPD(world, myPduNum, &myData);

See Also

int ossUnknownExtensionFound (OssGlobal *world);

Checks whether the last PDU decoded by the ossDecode() function contained at least one unknown SEQUENCE, SET, or CHOICE type extension. The presence of unknown extensions indicates that the sender is using a newer ASN.1 specification version.

Arguments

world
Pointer to the OssGlobal variable.

Return Value

  • 0 - when no unknown extensions are present.
  • 1 - when an unknown extension is present.
  • BAD_ARG - when the world pointer is NULL.
  • UNIMPLEMENTED - when the code is linked with the SOED or LEAN runtime or the ASN.1 specification was compiled by an OSS ASN.1/C compiler version prior to version 11.1.

Remarks

Note that this feature is disabled by default due to some performance and size overhead. To enable it, C-compile the generated code using the -DOSS_DETECT_UNKNOWN_EXTENSION option. If the feature is not enabled, the ossUnknownExtensionFound() function returns 0 regardless of the presence of unknown extensions.

Example

 
OssGlobal w, *world = &w;
int       rc, pdunum;
void      *data;
OssBuf    encodedData;
  . . . 
if (ossDecode(world, &pdunum, &encodedData, (void **)&data) == PDU_DECODED) {
    ossPrint(world, "PDU successfully decoded.\n");
    rc = ossUnknownExtensionFound(world);
    if (rc > 1)
        ossPrint(world, "ossUnknownExtensionFound() failed with return code %d!\n", rc);
    else
        ossPrint(world, "Unknown extension %sfound!\n", rc == 1 ? "" : "NOT ");
}

Prints:

Resulting string: Unknown extension found!

See Also

ossGetExtensionAddition()


Memory, File, and Socket Functions

The functions described in this section enable greater control over the storage and retrieval of data manipulated by the encoder/decoder. For more information, see Memory, File, Sockets, and PDU Handling.

OssMemoryHandle *ossCreateMemoryHandle(OssGlobal *world, size_t chunkLength);
int ossDeleteMemoryHandle(OssGlobal *world, OssMemoryHandle *hdl);

Substitutes or restores the default memory allocation of OssGlobal memory functions (OssGlobal.mallocp, OssGlobal.freep, etc.) with preallocated chunks of memory that can hold complete PDU data during subsequent encoding or decoding operations. You don't need to allocate memory dynamically during encoding or decoding, which means that performance is increased.

A memory handle controls every chunk (clean-up, delete, set active, etc.). You can create multiple chunks by calling ossCreateMemoryHandle() every time. However, only one chunk is active for every call. After the last chunk is deleted, the default memory allocation functions are restored in OssGlobal.

When using or customizing OssGlobal, other memory allocation functions will use the chunk under the active memory handle. Therefore, when using memory handles, make sure you do not specify the ossSetUserMallocFreeRealloc() function.

Arguments

world
Pointer to the OssGlobal variable.
chunkLength
Size of a memory block (chunk) that is allocated for the handle. If the memory fragment requested by the encoder or decoder or by the user application is smaller than chunkLength, it is taken from the existing chunk. If there is not enough free space in it, it is taken from a new chunk that is added to the list of chunks. When the size of a requested fragment exceeds chunkLength, that amount of memory is reallocated as a single new chunk. chunkLength must be twice the size of an average decoded or encoded PDU, or buffer size, so that you can perform a single encode or decode operation from one chunk of memory.

Return Value

If successful, ossCreateMemoryHandle() returns a new memory handle. Otherwise, it returns NULL.

If successful, ossDeleteMemoryHandle() returns zero.

Example

OssGlobal w, *world = &w;
OssMemoryHandle *encMemory;
  . . . 
if (!(encMemory = ossCreateMemoryHandle(world, DEFAULT_CHUNK_LENGTH)))
  appretcode = EXIT_FAILURE;
  . . . 
if ((retcode = ossEncode(world, BBCard_PDU, &myCard, &encodedData)) != 0) 
  appretcode = retcode;
  . . . 
if ((retcode = ossDeleteMemoryHandle(world, encMemory)) != 0) 
  appretcode = retcode;

Remarks

Memory handles decrease the number of calls to the system memory allocation or release functions. You can use one call for one or more decode operations.

Unlike user preallocated buffers, memory handles do not limit the size of encoded or decoded data. Each handle is a list of relatively large memory blocks (you set the minimal size of a block) from which the library allocates the output memory.

The content of memory handles is private and it is not described in OSS header files.

The ossCreateMemoryHandle() function returns NULL if the application is linked with the RTOED library and the generated codefile is C-compiled without the -DOSS_RTOED_MEMORY_HANDLES_SUPPORTED option.

See Also


int ossCleanMemoryHandle(OssGlobal *world, OssMemoryHandle *hdl);

Marks memory that is associated with the given memory handle as unused, without deallocating it on the system level (with world->freep). You can use it to rapidly free up and reuse memory on multiple encode or decode operations. Unlike ossFreePDU() or other similar functions, it does not traverse the decoded PDU tree, and does not call a system memory release function for each block of memory. To deallocate the handle, call the ossDeleteMemoryHandle() function.

Arguments

world
Pointer to the OssGlobal variable.
hdl
The memory handle that is cleaned.

Return Value

If successful, ossCleanMemoryHandle() returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w, *world = &w;
OssMemoryHandle *encMemory;
  . . . 
if (!(encMemory = ossCreateMemoryHandle(world, DEFAULT_CHUNK_LENGTH)))
  appretcode = EXIT_FAILURE;
  . . . 
if ((retcode = ossEncode(world, BBCard_PDU, &myCard, &encodedData)) != 0)  
 appretcode = retcode; 
 . . .  
if ((retcode = ossCleanMemoryHandle(world, encMemory)) != 0) { 
 appretcode = retcode; 
. . . 

See Also


long ossDetermineEncodingLength(OssGlobal *world, int pduid, void *data);

Returns the size of the encoded data that ossEncode() creates. You can find the size of the buffer for storing the output of the encoder without extensive memory allocations. This function is especially useful in applications that need to minimize the amount of allocated memory. When using this function, we recommend that you perform empirical test calls of ossEncode(), and check the OssBuf.length field after each call.

Arguments

world
Pointer to the OssGlobal variable.
pduid
The PDU ID of the compiler-generated data structure whose encoding length is determined.
data
Address of the data structure.

Return Value

If successful, ossDetermineEncodingLength() returns the number of bytes occupied by the encoding data. Otherwise, it returns a length of zero.

Example

OssGlobal w, *world = &w; 
OssBuf encodedData; 
int myPduid = MyASN1DataType_PDU; 
MyASN1DataType myData; 
long encodingLength; 
  . . .  
encodingLength = ossDetermineEncodingLength(world, myPduid, &myData); 
ossPrint(world, "Encoding Length: %ld.", encodingLength); 

See Also


unsigned long ossDetermineMessageLength(OssGlobal *world, OssBuf *buf);

Returns the total length (including tags, lengths, and contents) of a BER/DER definite-length encoding passed in a buffer.

Arguments

world
Pointer to the OssGlobal variable.
buf
Address of a valid BER encoding.

Return Value

If successful, ossDetermineMessageLength() returns the number of bytes occupied by the encoding data. If the buffer does not contain valid BER/DER definite-length encodings, it returns a value of zero.

Example

OssGlobal w, *world = &w; 
OssBuf encData; 
int myPduNum = MyASN1DataType_PDU; 
MyASN1DataType myData; 
. . .  
ossEncode(world, myPduNum, &myData, &encData); 
ossPrint(world, "Encoding length: %ld.", 
ossDetermineMessageLength(&encData)); 

Remarks

ossDetermineMessageLength() does not work with the file memory manager.

See Also


int ossDetermineNumberOfPadBits(OssGlobal *world);

Returns the number of extra bits padded to the end of a PER encoding (aligned or unaligned). This function is useful for those applications that must obtain the exact size of the encoding, excluding the trailing pad bits. This function checks the runtime environment to see how many pad bits were added by the encoder for the previous encoding. It is available for PER encodings.

Arguments

world
Pointer to the OssGlobal variable.

Return Value

If successful, ossDetermineNumberOfPadBits() returns the number of bits (zero to seven) padded to the last octet of the previous value encoded. If an error occurs, it returns a value that is less than zero or greater than seven.

See Also

ossPrintPER()


long ossDeterminePDUBufferLength(OssGlobal *world, int pdunum, void *data);

Returns the size of the buffer that ossPrintPDUToBuffer() would create if it were called to print the sent PDU. You can find the size of the buffer needed to store the output, without allocating memory with ossPrintPDUToBuffer(). This function is used primarily in applications that want to minimize the amount of memory allocated.

Arguments

world
Pointer to the OssGlobal variable.
pduNum
PDU number for the compiler-generated data structure to print out.
data
Address of the data structure to be printed.

Return Value

The ossDeterminePDUBufferLength() function returns a long INTEGER. If successful, it returns the number of octets to be occupied by the printed PDU value. Otherwise, it returns a length of zero.

Example

OssGlobal w, *world = &w;
int myPduNum = MyASN1DataType_PDU;
MyASN1DataType myData;
long bufferLength;


. . . . 

bufferLength = ossDeterminePDUBufferLength(world, myPduNum, &myData);
ossPrint(world, "Buffer Length:  %ld.\n", bufferLength);

See Also

ossPrintPDUToBuffer()


void *ossGetMemory(OssGlobal *world, size_t size);
void *ossGetInitializedMemory(OssGlobal *world, size_t size);
void ossFreeMemory(OssGlobal *world, void *ptr);

Allocates or deallocates a block of memory (similar to ossEncode() | ossDecode()). When you call the ossSetUserMallocFreeRealloc() function for custom memory allocation, deallocation, and reallocation, the custom memory allocator is used. If the memory handle is active, memory is taken or returned from or to the handle.

ossGetInitializedMemory() initializes the allocated block to zero.

Arguments

world
Pointer to the OssGlobal variable.
size
Size of the memory (in bytes) that is allocated.
ptr
Block of memory to deallocate.

Return Value

ossFreeMemory() does not return a value.

If successful, ossGetMemory() and ossGetInitializedMemory() return a pointer to the newly allocated block of memory. Otherwise, they return NULL.

Example

#define BUF_SIZE 1024 
OssGlobal w, *world = &w; 
OssBuf buf; 
. . .  
buf.value = (unsigned char *)ossGetMemory(world, BUF_SIZE); 
buf.length = BUF_SIZE; 
. . .  
ossFreeMemory(world, buf.value); 

Remarks

When you call ossCleanMemoryHandle() or ossDeleteMemoryHandle() while using memory handles, the memory block allocated by ossGetMemory() will also become obsolete.

These functions are especially used by helper macros and helper list API functions generated by the OSS ASN.1 compiler with -helperMacros, -helperListAPI command-line options or corresponding directives during ASN.1-compiling. They are hidden from the application that uses corresponding generated macro and function names.

If helper macros functions cannot be used with the application, it is recommended to explicitly call ossGetMemory() or ossFreeMemory() to allocate or deallocate memory, since they support custom memory and memory handles by default, and hide the memory handling details.

Do not use the ossGetMemory() function pointer as the first parameter for the ossSetUserMallocFreeRealloc() function. The pointer enforces ossGetMemory() to call itself, which will result an endless loop when trying to allocate memory.

See Also


OssMemoryHandle *ossGetActiveMemoryHandle(OssGlobal *world);
                          int ossSetActiveMemoryHandle(OssGlobal *world, OssMemoryHandle *hdl);

The ossSetActiveMemoryHandle() function instructs OSS API functions to back up and replace current memory allocation routines in OssGlobal with the given memory handle.

When the handle pointer is NULL, it instructs the library to disable the memory handle allocation mode and use the previously backed up ones (dynamic memory allocation mode, for example).

The ossGetActiveMemoryHandle() function returns a pointer to the memory handle that has been previously set by ossSetActiveMemoryHandle() or (implicitly) by ossCreateMemoryHandle(). A NULL is returned if there is no active memory handle.

Arguments

world
Pointer to the OssGlobal variable.
hdl
Memory handle that is used for all subsequent memory allocations.

Return Value

If successful, ossGetActiveMemoryHandle() returns the active memory handle. If there is none, it returns NULL.

If successful, ossSetActiveMemoryHandle() returns a value of zero. Otherwise, it returns a non-zero error code.

Example

OssGlobal w, *world = &w; 
OssMemoryHandle *encMemory, *decMemory; 
  . . .  
encMemory = ossCreateMemoryHandle(world, DEFAULT_CHUNK_LENGTH); 
decMemory = ossCreateMemoryHandle(world, DEFAULT_CHUNK_LENGTH); 
  . . .  
ossPrint(world, "Setting the encoder memory handle as active..."); 
if (ossSetActiveMemoryHandle(world, encMemory)) != 0)  
  . . . 
else if (ossGetActiveMemoryHandle(world) == encMemory) 
  ossPrint(world, "Using the encoder memory handle."); 
else if (ossGetActiveMemoryHandle(world) == decMemory) 
  ossPrint(world, "Using the decoder memory handle."); 
else if (ossGetActiveMemoryHandle(world) == NULL) 
  ossPrint(world, "Using the dynamic memory allocation mode."); 
. . .

See Also


int ossGetBuffer(OssGlobal *world, OssBufExtended *buf);
int ossSetBuffer(OssGlobal *world, OssBufExtended *buf);

Used with the file and socket memory manager.

ossSetBuffer() sets an initial buffer before reading encoded data from a TCP/IP socket or an input file. When you use this function, the decoder first reads the encodings in the initial buffer, then the encodings whose references are passed as input.

ossGetBuffer() returns the trailing buffer of undecoded data left from the previous call to the decoder in the TCP/IP socket or the set initial buffer.

When allocating memory for the OssBufExtended.value, use the (*world->mallocp)() function pointer. Upon completion of decoding, the decoder will free the initial buffer memory. Memory returned by ossGetBuffer() (OssBufExtended.value field) belongs to the memory manager and its contents may change upon subsequent calls of the ossDecode() function. Contents of the buffer may be overwritten when decoding from a file after decoding from a socket. To be able to use it after subsequent decoding operations, make a copy of the data returned by ossGetBuffer().

Arguments

world
Pointer to the OssGlobal variable.
buf
Information about the initial buffer to start decoding from, before reading encoded data from a TCP/IP socket or an input file. Before calling ossGetBuffer() set OssBufExtended.value and OssBufExtended.byteOffset to NULL and 0, respectively. After a successful return, buf will point to the desired trailing buffer.

Return Value

If successful, ossGetBuffer() | ossSetBuffer() returns zero. Otherwise, it returns CANT_SET_START_BUF.

Example

In the following example, the decoder decodes the encodings within initialBuf before decoding the encodings referenced through encodedData:

OssGlobal w, *world = &w; 
OssBuf encodedData; 
OssBufExtended initialBuf; 
int myPduNum = MyASN1DataType_PDU; 
  . . .  
initialBuf.value = (unsigned char *)ossGetMemory(1024); ; 
initialBuf.length = 1024; /* size of initial buffer */ 
initialBuf.byteOffset = 0; /* offset in buffer from where data starts */ 
/* populate initialBuf.value with the encoded data (say from file or network) */  
  . . .  
ossSetBuffer(world, &initialBuf); 
ossDecode(world, &myPduNum, &encodedData, (void **)&decodedDataPtr);

Remarks

When you call ossSetBuffer() after decoding from a TCP/IP socket, any undecoded data left from previous calls to the decoder are lost.

See Also

ossDecode()


long ossGetBytesReadByDecoder(OssGlobal *world);

Returns the number of bytes that the decoder reads from the input buffer during the previous decoding. This function is especially useful when decoding from a buffer containing multiple concatenated PDUs in either plain memory or a file.

Arguments

world
Pointer to the OssGlobal variable.

Return Value

If successful, ossGetBytesReadByDecoder returns the number of bytes read from the input buffer during the previous decoding. If an error occurs, the returned value reflects the position in the input buffer where the error was detected.

Example

OssGlobal w, *world = &w; 
OssBuf encodedData; 
int myPduNum = MyASN1DataType_PDU, rc; 
MyASN1DataType myData, *DecodedDataPtr; 
long bytesRead; 
  . . .  
rc= ossDecode(world, &myPduNum, &encodedData, (void **)&DecodedDataPtr); 
bytesRead = ossGetBytesReadByDecoder(world); 
if(rc) /* Decoder returned a failure code */ 
 ossPrint(world, "Error at position %ld in the buffer.", bytesRead); 
else /* Decoding finished successfully */ 
ossPrint(world, "%ld bytes decoded.", bytesRead); 

See Also

ossDecode()


long ossGetDecodingLength(OssGlobal *world);

Returns the total number of bytes occupied by the last decoded PDU. Note that the output buffer of the decoder does not need to consist of contiguously-allocated memory; rather, the decoded data may be stored in a tree structure. To copy the decoded data, use ossCpyValue() or copy each field separately, instead of using memcpy().

Arguments

world
Pointer to the OssGlobal variable.

Return Value

If successful, ossGetDecodingLength returns the total number of bytes occupied by the last decoded PDU. Otherwise, it returns a value of -1.

Example

OssGlobal w, *world = &w; 
OssBuf encodedData; 
int myPduNum = MyASN1DataType_PDU; 
MyASN1DataType myData, *DecodedDataPtr; 
long lengthOfDecodedData; 
  . . .  
ossDecode(world, &myPduNum, &encodedData, (void **)&DecodedDataPtr); 
lengthOfDecodedData = ossGetDecodingLength(world);

Remarks

To determine how much memory you should use for a preallocated output buffer for the decoder, call the ossGetDecodingLength() function repeatedly with different expected types of input data. By doing so, you can allocate more memory than the highest value received.

ossSetDecodingLength() overwrites the last decoding length stored by the decoder. Thus, you must call ossGetDecodingLength() after calling ossDecode() and before ossSetDecodingLength().

See Also

ossDecode()


int ossSetDecodingLength(OssGlobal *world, long bufferLength);

Indicates the output buffer length for the next invocation of ossDecode(). Must be called prior to every invocation of ossDecode() whenever the output buffer is preallocated.

Arguments

world
Pointer to the OssGlobal variable.
bufferLength
Length (in bytes) of the preallocated decoder output buffer.

Return Value

If successful, ossSetDecodingLength() returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w, *world = &w; 
OssBuf encodedData; 
int myPduNum = MyASN1DataType_PDU; 
void *DecodedDataPtr; 
  . . .  				
DecodedDataPtr= (void*)malloc(1024); /* preallocate output buffer */ 
  . . . 
ossSetDecodingLength(world, 1024);  
ossDecode(world, &myPduNum, &encodedData, (void **)&DecodedDataPtr); 

Remarks

The output buffer length applies only if the output buffer pointer is non-NULL.

See Also

ossDecode()


int ossGetMemoryHandleStat(OssGlobal *world, OssMemoryHandle *hdl,OssMemoryHandleStat *stat, unsigned int mode);

Fills memory usage statistics structure OssMemoryHandleStat for the memory handle passed on input. The mode argument controls the level of details and printing of the memory layout and fragments within a handle.

Arguments

world
Pointer to the OssGlobal variable.
hdl
Memory handle to inspect.
stat
Points to the OssMemoryHandleStat structure that is filled.
mode
Controls the function behavior.

The OssMemoryHandleStat structure is defined as:

typedef struct ossMemoryHandleStat { 
 unsigned int nodes; 
 size_t system_allocated; 
 struct { 
 size_t used_internally; 
 size_t user_allocated; 
 size_t user_free; 
 } detail; 
} OssMemoryHandleStat;

The following modes are currently defined:

#define OSS_MH_BRIEF 0 
#define OSS_MH_DETAIL 1 
#define OSS_MH_DETAIL_TRACE_HANDLE 2 
#define OSS_MH_DETAIL_TRACE_BLOCKS 3 
#define OSS_MH_DETAIL_TRACE_FRAGMENTS 4

For the OSS_MH_BRIEF mode, the function returns brief statistics, including the total amount of system memory allocated, system_allocated, and the number of memory chunks in use, nodes.

For the OSS_MH_DETAIL mode, the function returns the amount of actually used memory, user_allocated, the amount of available memory, user_free, and the amount of memory reserved for internal needs, used_internally. The sum of these three numbers is equal to the memory block size.

The remaining flags control the printing information produced by the function. The following code is produced with the OSS_MH_DETAIL_TRACE_FRAGMENTS flag:

Handle: 0x007c2bd0 
  Block #1 [0x007c6fb8]: 4128 bytes 
    Fragment #1 [0x007c6fd4]: status = 'free', length = 120 
    Fragment #2 [0x007c705c]: status = 'used', length = 192 
    Fragment #3 [0x007c712c]: status = 'last/free', length = 3768 
  Block summary (bytes): 192 allocated, 3888 free, 48 used internally 
Handle summary (bytes): 192 allocated, 3888 free, 84 used internally

The flag below can be used for any mode value to suppress printing pointers (values in brackets in the example above) which is useful when comparing results of multiple executions of the same test application:

#define OSS_MH_NO_PTR_IN_TRACE 0x20

Return Value

If successful, ossGetMemoryHandleStat() returns zero. Otherwise, it returns a non-zero value.

See Also


long ossGetMinFileSize(OssGlobal *world);
long ossSetMinFileSize(OssGlobal *world, long minsize);

Used with the file and socket memory managers. These functions get or set the data size threshold. The decoder will not create a temporary file to store the output of a type marked with the OSS.OBJHANDLE | NOCOPY directive. PDUs larger than the threshold are decoded to a temporary output file, while the ones smaller than the indicated threshold are decoded to regular memory.

By default, the threshold value is set to zero, thus forcing all values for types marked with OSS.OBJHANDLE | OSS.NOCOPY to be copied to temporary files. If the ossblock field of OssGlobal is set, the threshold cannot exceed it.

Arguments

world
Pointer to the OssGlobal variable.
minsize
The threshold value.

Return Value

ossGetMinFileSize() returns the threshold. ossSetMinFileSize() returns the threshold value. If the return value does not match the specified value, it might indicate that problems were encountered (the specified value was greater than the set ossblock variable, for example).

Example

OssGlobal w, *world = &w; 
long minFileSize; 
  . . . 
minFileSize = ossSetMinFileSize(world, 1024); 
if(minFileSize == 1024) 
  ossPrint(world, "Minimum threshold successfully set."); 
  . . . 
minFileSize = ossGetMinFileSize(world); 
if(minFileSize >= 1024) 
  ossPrint(world, "1kB chunks are in use."); 

See Also

OSS.OBJHANDLE | NOCOPY


void *ossMarkObj(OssGlobal *world, OssObjType objType, void *object);
void *ossUnmarkObj(OssGlobal *world, void *objHndl);
void *ossGetObj(OssGlobal *world, void *objHndl);

Used with the file, socket, and OSAK memory managers to associate the encoder or decoder data with a file, TCP/IP socket, or OSAK buffer as a source or destination of PDU values.

ossMarkObj() marks the value field of either an OssBuf or a length-value-pair structure referencing data in a file or a socket. It returns a handle to be passed to the encoder or decoder. To directly access data marked with the ossMarkObj() function, unmark the associated object with ossUnmarkObj().

Arguments

world
Pointer to the OssGlobal variable.
objType
Specifies which type of source or destination is intended for the object. The valid values for objTypeare OSS_FILE (for a file), OSS_SOCKET (for a socket), and OSS_OSAK (for a linked-list of OSAK buffers on the DEC UNIX or VMS platforms).
object
Can be either a pointer to a character string containing a filename (for a file), a socket identification number (for a socket), or an address of an OSAK buffer.
objHndl
Handle returned by ossMarkObj().

Return Value

If successful, ossMarkObj() returns a non-NULL handle to a file, socket, or OSAK buffer. Otherwise, a NULL handle (indicating memory problems were encountered) or a value of -1 (indicating that objType is not a valid object type) is returned.

If successful, ossGetObj() | ossUnmarkObj() returns the file name or the socket identification number containing the data. Otherwise, it returns OSS_UNKNOWN_OBJECT .

Example

In the following example, the encoder writes its output to the file named encoder.out. This file is given to the decoder to retrieve the original data. The ossMarkObj() function is called before calling the encoder, then before calling the decoder.

OssGlobal w, *world = &w; 
OssBuf encodedData; 
char charFilename[64]; 
int myPduNum = MyASN1DataType_PDU; 
MyASN1DataType myData; 
MemMgrHdl = ossLoadMemoryManager(world, OSS_FILE_MEMMGR, NULL); 
  . . . 
encodedData.value = ossMarkObj(world, OSS_FILE, "encoder.out"); encodedData.length = 0; 
ossEncode(world, myPduNum, &myData, &encodedData); 
  . . . 
ossPrint(world, "Encoding file %s",
ossGetObj(world, encodedData.value)); 
  . . .  
encodedData.value = ossMarkObj(world, OSS_FILE, "encoder.out"); 
encodedData.length = 0; 
ossDecode(world, &myPduNum, &encodedData, (void **)&DecodedDataPtr); 
  . . . 
ossFreeBuf(world, encodedData.value); /* free buffer for encoded data */

Remarks

To delete a temporary output file when calling ossFreePDU(), make sure it remains "marked".

To encode from a file and decode to a temporary file, use the OSS.OBJHANDLE | OSS.NOCOPY directive. To encode to a file and decode from a file, you do not need to use the OSS.OBJHANDLE | OSS.NOCOPY directive.

When you use these functions, specify the file or socket memory manager library file (ossfmgmt.obj or osssmgmt.obj) before the SOED library file (ssoeddefa.lib).

See Also


void ossGetUserMallocFreeRealloc(OssGlobal *world,
           void *(CDECL_ENTRY_FPTR **ossUserMalloc)(OssGlobal *world, size_t size),
           void (CDECL_ENTRY_FPTR **ossUserFree)(OssGlobal *world, void *buf),
            void *(CDECL_ENTRY_FPTR **ossUserRealloc)(OssGlobal *world, void *buf, size_t size));
void ossSetUserMallocFreeRealloc(OssGlobal *world,
            void *(CDECL_ENTRY_FPTR *ossUserMalloc)(OssGlobal *world, size_t size),
            void (CDECL_ENTRY_FPTR *ossUserFree)(OssGlobal *world, void *buf),
            void *(CDECL_ENTRY_FPTR *ossUserRealloc)(OssGlobal *world, void *buf, size_t size));

Sets or gets memory allocation, deallocation, and reallocation functions used by the encoder or decoder. By default, allocation, deallocation, and reallocation operations are performed by malloc(), free(), and realloc() C functions, respectively (stored as pointers in world->mallocp, world->freep, and world->reallocp).

Arguments

world
Pointer to the OssGlobal variable.
ossUserMalloc, ossUserFree, ossUserRealloc
Function pointers to a user-defined memory allocating, deallocating, and reallocating functions.

Example

OssGlobal myWorld, *w = &myWorld; 
void *(CDECL_ENTRY_FPTR *oldMallocp)(OssGlobal *world, size_t size); 
void *(CDECL_ENTRY_FPTR *oldReallocp)(OssGlobal *world, void *buf, size_t size); 
void (CDECL_ENTRY_FPTR *oldFreep)(OssGlobal *world, void *buf); 
void * CDECL_ENTRY_FDEF myMalloc(OssGlobal *world, size_t size){...}; 
void * CDECL_ENTRY_FDEF myRealloc(OssGlobal *world, void *buf, size_t size){...}; 
void CDECL_ENTRY_FDEF myFree(OssGlobal *world, void *buf){...}; 
  . . . 
/* Save original and set new allocation functions */ 
ossGetUserMallocFreeRealloc(w, &oldMallocp, &oldFreep, &oldReallocp); 
ossSetUserMallocFreeRealloc(w, myMalloc, myFree, myRealloc); 
  . . . 
/* Restore original allocation functions */ 
ossSetUserMallocFreeRealloc(w, oldMallocp, oldFreep, oldReallocp); 
. . .

HINSTANCE ossLoadMemoryManager(OssGlobal *world, OssMemMgrType type, char *dllName);

Available on the Microsoft Windows platform. Enables the user to switch between the available memory managers at run time. The memory managers are used by the encoder/decoder to handle allocation, deallocation, storage, and retrieval of data. For more information about the OSS memory managers, see Memory, File, Sockets, and PDU handling.

Arguments

world
Pointer to the OssGlobal variable.
type
Specifies the memory manager that is loaded, using the values below.
  • OSS_DEFAULT_MEMMGR: memory is malloc'ed for each pointer in the data tree.
  • OSS_FILE_MEMMGR: file manager with capability to redirect data streams in files.
  • OSS_SOCKET_MEMMGR: TCP/IP socket manager capability to redirect data streams in sockets.
  • OSS_OSAK_MEMMGR: OSAK-buffer memory manager, available only on the DEC UNIX and OpenVMS platforms.
  • OSS_USER_MEMMGR: user custom-built memory manager, implemented via DLL and provided via the dllName argument (in all other cases dllName should be set to NULL).

Return Value

If successful, ossLoadMemoryManager() returns the handle of the loaded DLL. Otherwise, it returns a value of zero.

Example

OssGlobal w, *world = &w; 
HINSTANCE MemMgrHdl; 
  . . . 
MemMgrHdl = ossLoadMemoryManager(world, OSS_FILE_MEMMGR, NULL); 
if (!MemMgrHdl)  				
ossPrint(world, "File memory manager not loaded."); 
  . . . 

Remarks

When freeing a PDU, make sure you use the same memory manager that was used to create it.

See Also


int ossOpenDecoderInputFile(OssGlobal *world, char *fname);
int ossCloseDecoderInputFile(OssGlobal *world);
int ossOpenEncoderOutputFile(OssGlobal *world, char *fname);
int ossCloseEncoderOutputFile(OssGlobal *world);

These functions are used with the file and socket memory managers. The "open" functions enable you to keep the specified file open across multiple decoder or encoder operations. This is useful for applications that decode or encode multiple concatenated PDUs from or to a file. Thus, you can avoid the extra overhead experienced while opening files multiple times. To associate the encoding file with the encoder or decoder, call the ossMarkObj() function.

Arguments

world
Pointer to the OssGlobal variable.
fname
The name of the file containing the encoded PDU for the decoder or encoder to read or write.

Return Value

If successful, the value returned is zero. Otherwise, the value returned is non-zero.

Example

OssGlobal w, *world = &w; 
OssBuf encodedData; 
int myPduNum = MyASN1DataType_PDU; 
MyASN1DataType *DecodedDataPtr = NULL; 
char charFilename[64]; 
  . . .  
encodedData.value = (unsigned char *)ossMarkObj(world, OSS_FILE, "encoded.ber"); 
encodedData.length = 0; 
ossOpenDecoderInputFile(world, "encoded.ber"); 
ossDecode(world, &myPduNum, &encodedData, (void **)&decodedDataPtr); 
  . . . 
ossCloseDecoderInputFile(world); 

Remarks

When you use the same file as encoder output and as decoder input file in the same application, you must call ossCloseEncoderOutputFile() before calling ossOpenDecoderInputFile().

To decode or encode a single PDU from or to a file, you can call the ossMarkObj() function, while passing it the filename each time before calling the decoder/encoder, instead of using "open" or "close" functions.

See Also

ossMarkObj()


void ossSetTimeout(OssGlobal *world, long timeout);

Used with the socket memory manager to set a timeout for TCP/IP sockets read or write operations during decoding or encoding from or to a TCP/IP socket. Allows recv() and send() socket functions to complete without blocking.

Arguments

world
Pointer to the OssGlobal variable.
timeout
Maximum socket wait time specified in seconds.

int ossSkipPadBytes(OssGlobal *world, OssBuf *input, unsigned char pad_byte);

Enables you to skip pad bytes in the input encoding. The OssBuf.value is advanced until it points to the next byte that does not match pad_byte. OssBuf.length is reduced by the number of skipped bytes. For SOED, ossSkipPadBytes() can be used with the file or socket memory manager, in which case it may fail with a OSS_TIMEOUT_EXPIREDor other non-fatal socket errors. The function can be called multiple times to obtain a successful outcome.

Arguments

world
Pointer to the OssGlobal variable.
input
Address of an OssBuf containing the encoding.
pad_byte
The byte that is skipped.

Return Value

If successful, ossSkipPadBytes() returns a value of zero. Otherwise, it returns a non-zero value. When all pad bytes are skipped and the non-pad byte is not reached, it returns the MORE_INPUT error.

Remarks

When using ossSkipPadBytes(), do not call ossDecode() unless ossSkipPadBytes() returned successfully.

See Also

ossDecode()


OssObjType ossTestObj(OssGlobal *world, void *objHndl);

Used to check whether objHndl is a file handle, a socket handle, an address of a linked-list of OSAK buffers (DEC UNIX and VMS only), or a regular memory address.

Arguments

world
Pointer to the OssGlobal variable.
objHndl
Is either a handle which the ossMarkObj() function returned or a memory address (OSS_UNKNOWN_OBJECT is returned for such memory).

Return Value

One of the following values:

  • OSS_FILE, for file.
  • OSS_SOCKET, for socket
  • OSS_OSAK, for OSAK buffers.
  • OSS_UNKNOWN_OBJECT, for unrecognized handles.

Example

switch(ossTestObj(world, encodedData.value))				 
{ 
  case OSS_FILE: ossPrint(world, "This handle is a file handle."); 
    break; 
  case OSS_SOCKET: ossPrint(world, "This handle is a socket handle."); 
    break; 
  default: ossPrint(world, "This is a non-file/non-socket handle."); 
    break; 
}

Remarks

If ossTestObj() is called for the decoder's output value, it returns the enumerator OSS_FILE for values that are stored in temporary files, in accordance with the applied OSS.OBJHANDLE | OSS.NOCOPY directive.

See Also


typedef struct OssBuf { long length; unsigned char *value; } OssBuf;
typedef struct OssBufExtended { long length; unsigned char *value; long byteOffset; } OssBufExtended;

The encoder or decoder uses the OssBuf structure to write or read the encoded data. The OssBufExtended structure allows the user to store and retrieve an initial buffer to start decoding from before starting to read data from a file or socket (can contain undecoded data from the last TCP/IP socket read by the decoder.

Fields

value
A contiguous memory buffer of encoded data.
length
A number of bytes occupied by value.
byteOffset
Indicates the offset to the undecoded (from the last TCP/IP socket read) data or the position in the initial buffer to start decoding from.

Specialized Functions

The functions described in this section are used for performing specialized tasks such as: conversions, copying or comparing ASN.1 messages, runtime manipulation of ASN. 1 Information Object Sets, handling multi-threading, backward compatibility, etc.

int ossAddInfoObject(OssGlobal *world, int objSetNumber, void *object);
int ossRemoveInfoObject(OssGlobal *world, int objSetNumber, void *object);

Enable you to manipulate Information Object Sets at run time, by adding an object to an extensible Information Object Set. The ossRemoveInfoObject() function removes the previously added object.

Arguments

world
Pointer to the OssGlobal variable.
objSetNumber
ID of the Information Object Set (InfoObjSetName_OSET).
object
Address of the Information Object.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

TCIP_CLASS newInfoObj;
ObjectSetEntry *myObjSet;
OssEncodedOID encodedOID;
  . . .
newInfoObj.Type=2;
newInfoObj.description = malloc(16*sizeof(char));
strcpy(newInfoObj.description, "A new Info Obj.");
encodedOID.value = NULL;
encodedOID.length = 0;
ossAsnValToEncodedOid(&world, "{0 4}", &encodedOID);
  . . .
newInfoObj.id.length = encodedOID.length;
newInfoObj.id.value = encodedOID.value;
ossAddInfoObject(world, TCIP_ObjSet_OSET, &newInfoObj);
. . .
ossRemoveInfoObject(world, TCIP_ObjSet_OSET, &newInfoObj);
free(newInfoObj.description);
ossPrint(world, "After removal, set looks like:\n");
myObjSet = ossGetInfoObjectSet(world, TCIP_ObjSet_OSET);
while(myObjSet != NULL)
{ /* print out address and description for each element in set */
  myInfoObj = (TCIP_CLASS *)myObjSet->object;
  ossPrint(world, "ObjSet @%d, %s\n", myObjSet->object, myInfoObj->description);
  myObjSet = myObjSet->next;
}
ossFreeBuf(world, encodedOID.value);

Remarks

You cannot use the ossRemoveInfoObject() function to remove Information Objects defined in your ASN.1 schema. To remove them, modify your ASN.1 specifications and recompile. However, you can use ossRemoveInfoObject() to remove dynamically added Information Objects.

To free memory associated with Information Objects, use ossterm() | ossWterm(), unless you have explicitly allocated memory (through malloc()).

To use TOED with Information Object handling functions, ASN.1-compile your schema with the -autoEncDec and -toed compiler options.

To make these functions available at run time, C-compile the generated code file with -DOSS_INFOOBJ_API.

See Also


int ossAsnValToEncodedOid(OssGlobal *world, const char *valOID, OssEncodedOID *encodedOID);
int ossAsnValToEncodedRelOid(OssGlobal *world, const char *valOID, OssEncodedOID *encodedOID);

These functions convert the value of an OBJECT IDENTIFIER or a RELATIVE-OID, respectively, from a string to the ENCODED C-representation structure, which is required before passing Object Identifiers to the encoder. The C-representation structure is defined as follows:

typedef struct {
  unsigned short length;
  unsigned char *value;
} OssEncodedOID;

value is a pointer to a byte array containing the encoded data, as BER value, without tag and length:

OBJECT IDENTIFIER "{1 2 3 4 5}" converted to: 0x2A, 0x03, 0x04, 0x05

length is the size of the array in bytes: 4, in this case.

Arguments

world
Pointer to the OssGlobal variable.
valOID
String pointer containing an OBJECT IDENTIFIER or RELATIVE-OID in the form "{X Y Z}" (including quotes).
encodedOID
Output structure for the ENCODED value. To allocate the output memory, set the length and value fields to NULL and 0, respectively. To deallocate it, use ossFreeBuf(). Otherwise, preallocate the output buffer to fit the value, and initialize the fields accordingly.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal world;
OssBuf encodedData;
OssEncodedOID encodedOID;
ObjectID OIDvalue;
int rc, pdunum = 1;
cchar *asnValue = "{1 2 3 418446744073709551615 456}";
  . . .
encodedOID.value = NULL;
encodedOID.length = 0;
ossAsnValToEncodedOid(&world, asnValue, &encodedOID);
OIDvalue.length = encodedOID.length;
OIDvalue.value = encodedOID.value;			
ossEncode(&world, pdunum, &OIDvalue, &encodedData);

See Also


int ossBinary2AVN(OssGlobal *world, int pdunum, ossEncodingRules sourceRules, OssBuf *binSource, OssBuf *avnTarget);
int ossAVN2Binary(OssGlobal *world, int pdunum, ossEncodingRules targetRules, OssBuf *avnSource, OssBuf *binTarget);

The ossBinary2AVN() and ossAVN2Binary() functions enable conversion between the standard ASN.1 binary encoding rules (BER, CER, DER, PER, CPER, OER, and COER) and the AVN encoding rules.

Arguments

world
Pointer to the OssGlobal variable.
pdunum
The PDU number of the type to which the encoded data corresponds.
sourceRules
An enumerator that specifies the encoding rules of the binary ASN.1 encoding to convert from (OSS_BER, OSS_CER, OSS_DER, OSS_PER_ALIGNED, for example).
targetRules
An enumerator that specifies the encoding rules of the binary ASN.1 encoding to convert to (OSS_BER, OSS_CER, OSS_DER, OSS_PER_ALIGNED, for example).
binSource
A pointer to an OssBuf structure whose value field references the binary encoded ASN.1 value and whose length field contains the length in bytes of this value.
avnSource
A pointer to an OssBuf structure whose value field references the AVN encoded ASN.1 value and whose length field contains the length in bytes of this value.
binTarget
A pointer to an OssBuf structure whose value field references the output binary ASN.1 encoding corresponding to the input AVN value.
avnTarget
A pointer to an OssBuf structure whose value field references the output text of the AVN encoding corresponding to the input binary encoded ASN.1 value.

Remarks

Note for ossBinary2AVN()

To allow the OSS Nokalva runtime to automatically allocate and determine the length of the space required for the output, you can set the value field of avnTarget to NULL and the length field to 0 before calling this function. To free up the automatically allocated memory when it is no longer needed, you can call ossFreeBuf() for the avnTarget.value field.

Note for ossAVN2Binary()

To allow the OSS Nokalva runtime to automatically allocate and determine the length of the space required for the output, you can set the value field of binTarget to NULL and the length field to 0 before calling this function. To free up the automatically allocated memory when it is no longer needed, you can call ossFreeBuf() for the binTarget.value field.

Alternatively, you can preallocate your own memory buffer for the output and set the value field to reference it and the length field to contain the length in bytes of the allocated buffer. To free up the used memory when it is no longer needed, you should call your standard memory deallocation function.

The ossBinary2AVN() and ossAVN2Binary() functions perform conversion by decoding and then re-encoding the input message. The functions check if, at decoding stage, an open type or contents constrained type is left undecoded. This is possible when component relation constraints cannot be resolved for an extensible open type, when the OSS.NoConstrain compiler directive is applied to an open or contents constrained type, or when you use the TOED library without specifying the -autoencdec and -constraints options at ASN.1 compile time. Such an undecoded type cannot be converted. In this case, the functions issue the D0373S error and return the CONVERSION_NOT_POSSIBLE code.

Return Value

The ossBinary2AVN() and ossAVN2Binary() functions return an integer. If the input was successfully converted, a value of zero is returned; otherwise, a non-zero value is returned.

General Note

Support for ASN.1 Value Notation encoding rules is a chargeable feature in the time-optimized encoder/decoder of non-evaluation licenses. Contact Sales to obtain pricing information.


int ossBinary2JSON(OssGlobal *world, int pdunum, ossEncodingRules sourceRules, OssBuf *binSource, OssBuf *jsonTarget);
int ossJSON2Binary(OssGlobal *world, int pdunum, ossEncodingRules targetRules, OssBuf *jsonSource, OssBuf *binTarget);

The ossBinary2JSON() and ossJSON2Binary() functions enable conversion between the standard ASN.1 binary encoding rules (BER, CER, DER, PER, CPER, OER, and COER) and the JSON encoding rules.

Arguments

world
Pointer to the OssGlobal variable.
pdunum
The PDU number of the type to which the encoded data corresponds.
sourceRules
An enumerator that specifies the encoding rules of the binary ASN.1 encoding to convert from (OSS_BER, OSS_CER, OSS_DER, OSS_PER_ALIGNED, for example).
targetRules
An enumerator that specifies the encoding rules of the binary ASN.1 encoding to convert to (OSS_BER, OSS_CER, OSS_DER, OSS_PER_ALIGNED, for example).
binSource
A pointer to an OssBuf structure whose value field references the binary encoded ASN.1 value and whose length field contains the length in bytes of this value.
jsonSource
A pointer to an OssBuf structure whose value field references the JSON encoded ASN.1 value and whose length field contains the length in bytes of this value.
binTarget
A pointer to an OssBuf structure whose value field references the output binary ASN.1 encoding corresponding to the input JSON value.
jsonTarget
A pointer to an OssBuf structure whose value field references the output text of the JSON encoding corresponding to the input binary encoded ASN.1 value.

Remarks

  • Note for ossBinary2JSON(): To allow the OSS Nokalva runtime to automatically allocate and determine the length of the space required for the output, you can set the value field of jsonTarget to NULL and the length field to 0 before calling this function. To free up the automatically allocated memory when it is no longer needed, you can call ossFreeBuf() for the jsonTarget.value field.
  • Note for ossJSON2Binary(): To allow the OSS Nokalva runtime to automatically allocate and determine the length of the space required for the output, you can set the value field of binTarget to NULL and the length field to 0 before calling this function. To free up the automatically allocated memory when it is no longer needed, you can call ossFreeBuf() for the binTarget.value field.
  • Alternatively, you can preallocate your own memory buffer for the output and set the value field to reference it and the length field to contain the length in bytes of the allocated buffer. To free up the used memory when it is no longer needed, you should call your standard memory deallocation function.
  • The ossBinary2JSON() and ossJSON2Binary() functions perform conversion by decoding and then re-encoding the input message. Starting with version 11.0, the functions check if, at decoding stage, an open type or contents constrained type is left undecoded. This is possible when component relation constraints cannot be resolved for an extensible open type, when the OSS.NoConstrain compiler directive is applied to an open or contents constrained type, or when you use the TOED library without specifying the -autoencdec and -constraints options at ASN.1 compile time. Such an undecoded type cannot be converted. In this case, the functions issue the D0373S error and return the CONVERSION_NOT_POSSIBLE code.

Return Value

The ossBinary2JSON() and ossJSON2Binary() functions return an integer. If the input was successfully converted, a value of zero is returned; otherwise, a non-zero value is returned.

Version Information

The ossBinary2JSON() and ossJSON2Binary() functions are available since version 10.3.


int ossCallerIsDecoder(OssGlobal *world);

Checks whether the caller of the current function is ossDecode() or ossEncode(). This function must be called either from a custom memory manager or by the callback function associated with a user-defined subtype constraint.

Arguments

world
Pointer to the OssGlobal variable.

Return Value

When the caller is ossDecode(), the function returns a non-zero value. When the caller is ossEncode(), it returns zero.

Example

if(ossCallerIsDecoder(world))
{ /* allocate memory for decoded structure */
   . . . .
}
else
{ /* allocate memory for encoding */
   . . . .
}

int ossCalTimeToGenTimeString(OssGlobal *world, time_t in, int mindiff, char **out);
int ossCalTimeToUTCTimeString(OssGlobal *world, time_t in, int mindiff, char **out);

Converts a time_t standard ANSI type value into a GeneralizedTime or UTCTime ASN.1 value notation format, respectively.

Arguments

world
Pointer to the OssGlobal variable.
in
Address of an input calendar time value.
mindiff
Input minute differential (a value of 0 indicates that UTC time should be in use in the output value).
out
Address of a string that returns the time represented as ASN.1 value string. If the pointer is NULL, the function allocates the memory for the output value. You must free the pointer after using it. Otherwise you can preallocate memory for the string.

Return Value

If successful, it returns zero. Otherwise, it returns one of these values: BAD_ARG, BAD_TIME, OUT_MEMORY.

Example

Note that error checking is omitted for clarity:

OssGlobal w, *world = &w;
int ret;
time_t tt;
GeneralizedTime gt, *pgt = &gt;
char *str = "20040301112548.25-0600", *pbuf = NULL;
  . . .
ossPrint(world, "GeneralizedTime string: %s\n", str);
ossGenTimeStringToCalTime(world, str, &tt);
ossPrint(world, "Calendar time: %d\n", tt);
ossCalTimeToGenTimeStruct(world, tt, -360, &pgt);
ossPrint(world, "GenneralizedTime struct:\n"
 
" year: %d\n month: %d\n day: %d\n"
 
" hour: %d\n minute: %d\n second: %d\n millisec: %d\n"

" mindiff: %d\n utc: %d\n",
pgt->year, pgt->month, pgt->day, pgt->hour, pgt->minute,

pgt->second, pgt->millisec, pgt->mindiff, pgt->utc);
ossGenTimeStructToCalTime(world, pgt, &tt);
ossPrint(world, "Calendar time: %d\n", tt);
ossCalTimeToGenTimeString(world, tt, -360, &pbuf);
ossPrint(world, "GenneralizedTime string: %s\n", pbuf);
ossFreeMemory(world, pbuf);

Output:

GeneralizedTime string: 
20040301112548.25-0600
Calendar time: 1078161948
GenneralizedTime struct:
year: 2004
month: 3
day: 1
hour: 11
minute: 25
second: 48
millisec: 0
mindiff: -360
utc: 0
Calendar time: 1078161948
GenneralizedTime string: 20040301112548-0600

See Also


int ossCalTimeToGenTimeStruct(OssGlobal *world, time_t in, int mindiff, GeneralizedTime **out);
int ossCalTimeToUTCTimeStruct(OssGlobal *world, time_t in,int mindiff, UTCTime **out);

Converts a time_t standard ANSI type value into a GeneralizedTime or UTCTime value, respectively.

Arguments

world
Pointer to the OssGlobal variable.
in
Address of an input calendar time value.
mindiff
Input minute differential (a value of 0 indicates that UTC time should be in use in the output value).
out
Time represented as ASN.1 value string. If the pointer is NULL, the function allocates memory for the output value. You must free the pointer after using it. Otherwise, you can preallocate memory for the string.

Return Value

If successful, it returns zero. Otherwise, it returns one of these values: BAD_ARG, BAD_TIME, OUT_MEMORY.

See Also


int ossCheckConstraints(OssGlobal *world, int pdunum, void *data);

Checks whether schema constraints are satisfied in an unencoded PDU. By default, the encoder/decoder performs constraint checking, which can be disabled by the NOCONSTRAIN flag (through ossSetFlags()). This function allows you to check constraints on a type without calling the encoder/decoder.

Arguments

world
Pointer to the OssGlobal variable.
pdunum
ID of the compiler-generated PDU data structure.
data
Address of the PDU whose value is checked.

Return Value

If successful, it returns zero. Otherwise, it returns an error code.

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
MyASN1DataType myData;
int rc;
  . . . 

if (rc = ossCheckConstraints(world, MyASN1DataType_PDU, &myData)) {
   ossPrint(world, "Constraint check failed: returncode = %d\n", rc); 
   exit(1); 
} else {
   ossEncode(world, MyASN1DataType_PDU, &myData, &encodedData);
} 

Remarks

To use the ossCheckConstraints() function with the TOED, compile your ASN.1 specification with the -constraints option specified. Note that not all constraints are supported for this function when linking with the TOED library, except for component relation constraints.


int ossCmpValue (OssGlobal *world, int pdunum, void *value1, void *value2);

Compares two unencoded PDUs to check if their values are equal. The values are considered equal if their known components are equal. If there are no known components (for example, two CHOICE values with unrecognized extension additions (zero CHOICE selector)), they are considered equal.

Arguments

world
Pointer to the OssGlobal variable.
pdunum
INTEGER containing a compiler-generated PDU number.
value1 and value2
Addresses of two unencoded PDUs.

Return Value

If data structures are equal, returns zero. If they are not equal, returns 1. Otherwise, returns en error code:

  • if value1 or value2 is NULL, returns BAD_ARG
  • if pdunum is invalid, returns PDU_RANGE
  • for TOED compiled without the OSS_COMPARE_VALUE defined, returns UNIMPLEMENTED

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
MyASN1DataType myData1, myData2;
  . . . 
if(!ossCmpValue(world, MyASN1DataType_PDU, &myData1, &myData2)
ossPrint(world, "Values are equal.\n");

Remarks

This function cannot be used for types marked with the OSS.OBJHANDLE | OSS.NOCOPY directive that do not reside in plain memory.

To support this function, TOED builds must be C-compiled with the OSS_COMPARE_VALUE defined.

See Also

ossCpyValue()


int ossConvertBCDStringToOctet (OssGlobal *world, char *BCD_str, unsigned int str_len, unsigned char **oct_str, unsigned int *length);

Converts a BCD string value into an OCTET STRING type value. The function was added in version 10.2.0.

Arguments

world
Pointer to the OssGlobal variable.
BCD_str
Points to the null-terminated BCD string value.
str_len
The length of the BCD_str value.
oct_str
Points to the address of the buffer where the resulting OCTET STRING type value is stored.
length
Points to the length of the OCTET STRING value.

Return Value

The ossConvertBCDStringToOctet() function returns an integer. When conversion succeeds, a value of zero is returned. When either world, oct_str, or BCD_str is a NULL pointer, the function returns the BAD_ARG enumerator. When the input data contains invalid characters, a value of DATA_ERROR is returned. When ossGetMemory() cannot allocate memory for the output string, a value of OUT_MEMORY is returned.

Example

	OssGlobal    	w, *world = &w;
	char   		    *bcd_str  = "250961278";
     	unsigned char    *buf = NULL;
     	unsigned int     os_len;
	int          	     err;

	. . . . 
    	ossPrint(world, "Source BCD string: %s\n", bcd_str);
    	ossPrint(world, "Call ossConvertBCDStringToOctet()... ");
    	err = ossConvertBCDStringToOctet(world, bcd_str, strlen(bcd_str), &buf, &os_len);
    	if (err == 0) {
        ossPrint(world, "conversion succeeded.\n");
        ossPrint(world, "Resulting octet string: \n");
        ossPrintHex(world, (char *)buf, os_len);
        ossFreeMemory(world, buf);
    	} else {
        ossPrint(world, "conversion failed with return code %d\n", err);
    	}
	. . . .     

ossConvertBCDStringToOctet() sample output:

Source BCD string: 250961278
Call ossConvertBCDStringToOctet()... conversion succeeded.
Resulting octet string: 25096127 8F

Remarks

When oct_str points to NULL, the ossConvertBCDStringToOctet() function will automatically allocate space for the output string. When you preallocate memory for the output string, you must set the oct_str pointer to reference the beginning of your memory block.

When you use the ossConvertBCDStringToOctet() function to allocate memory, you must call the ossFreeMemory() function and pass the returned oct_str pointer to it when your application no longer needs the output string. If you allocated memory for the output string, be sure to deallocate it when the memory is no longer needed.

See Also


int ossConvertOctetToBCDString (OssGlobal *world, unsigned char *oct_str, unsigned int length, char **BCD_str);

Converts an OCTET STRING type value into a BCD string value. The function was added in version 10.2.0.

Arguments

world
Pointer to the OssGlobal variable.
oct_str
A character string pointer that references the binary format input value notation of the OCTET STRING type.
length
The length, in bytes, of the OCTET STRING value.
BCD_str
Points to the address of an output null-terminated BCD string value.

Return Value

The ossConvertOctetToBCDString() function returns an integer. When conversion succeeds, a value of zero is returned. When either world, oct_str or BCD_str is a NULL pointer, the function returns the BAD_ARG enumerator. When the input string contains a nibble whose value is in the range 0xA - 0xE, or, when the nibble is set to 0xF (the filler nibble), but it is not the last one within the string, a value of DATA_ERROR is returned. When ossGetMemory() cannot allocate memory for the output string, a value of OUT_MEMORY is returned.

Example

	OssGlobal    	w, *world = &w;
	unsigned char   os_val[] = { 0x25, 0x09, 0x61, 0x27, 0x8F };
     	unsigned int    os_len = sizeof(os_val);
     	char        	*buf = NULL;
	int          	err;
	. . . . 
    	ossPrint(world, "Source octet string: ");
    	ossPrintHex(world, (char *)os_val, os_len);
    	ossPrint(world, "Call ossConvertOctetToBCDString()... ");
    	err = ossConvertOctetToBCDString(world, os_val, os_len, &buf);
    	if (err == 0) {
        ossPrint(world, "conversion succeeded.\n");
        ossPrint(world, "Resulting BCD string: %s\n", buf);
        ossFreeMemory(world, buf);
    	} else {
        ossPrint(world, "conversion failed with return code %d\n", err);
    	}
	. . . .      

ossConvertOctetToBCDString() sample output:

Source octet string: 25096127 8F
Call ossConvertOctetToBCDString()... conversion succeeded.
Resulting BCD string: 250961278

Remarks

If BCD_str points to NULL, the function will automatically allocate the space for the output string. When you preallocate memory for the output string, you must set the BCD_str pointer to reference the beginning of your memory block.

When you use the ossConvertOctetToBCDString() function to allocate memory, you must call the ossFreeMemory() function and pass the returned BCD_str pointer to it when your application no longer needs the output string. If you allocate memory for the output string, be sure to deallocate it when the memory is no longer needed.

See Also


int ossConvertOctetToTBCDString (OssGlobal *world, unsigned char *oct_str, unsigned int length, char **TBCD_str);

Converts an OCTET STRING type value into a TBCD string value. The function was added in version 10.2.0.

Arguments

world
Pointer to the OssGlobal variable.
oct_str
A character string pointer that references the binary format input value notation of the OCTET STRING type.
length
The length, in bytes, of the OCTET STRING value.
TBCD_str
Points to the address of an output null-terminated TBCD string value.

Return Value

The ossConvertOctetToTBCDString() function returns an integer. When conversion succeeds, a value of zero is returned. When either world, oct_str, or TBCD_str is a NULL pointer, the function returns the BAD_ARG enumerator. When the filler 0xF is present in the input string but is not the last nibble, a value of DATA_ERROR is returned. When ossGetMemory() cannot allocate memory for the output string, a value of OUT_MEMORY is returned.

Example

	OssGlobal    	w, *world = &w;
	unsigned char   os_val[] = { 0x25, 0x09, 0xA1, 0x2C, 0xEF };
     	unsigned int    os_len = sizeof(os_val);
     	char        	*buf = NULL;
	int          	err;
	. . . . 
    	ossPrint(world, "Source octet string: ");
    	ossPrintHex(world, (char *)os_val, os_len);
    	ossPrint(world, "Call ossConvertOctetToTBCDString()... ");
    	err = ossConvertOctetToTBCDString(world, os_val, os_len, &buf);
    	if (err == 0) {
        ossPrint(world, "conversion succeeded.\n");
        ossPrint(world, "Resulting TBCD string: %s\n", buf);
        ossFreeMemory(world, buf);
    	} else {
        ossPrint(world, "conversion failed with return code %d\n", err);
    	}
	. . . .      

ossConvertOctetToTBCDString() sample output:

Source octet string: 2509A12C FE
Call ossConvertOctetToTBCDString()... conversion succeeded.
Resulting TBCD string: 52901*a2c

Remarks

If TBCD_str points to NULL, the function will automatically allocate space for the output string. When you preallocate memory for the output string, you must set the TBCD_str pointer to reference the beginning of your memory block.

When you use the ossConvertOctetToTBCDString() function to allocate memory, you must call the ossFreeMemory() function and pass the returned TBCD_str pointer to it when your application no longer needs the output string. If you allocated memory for the output string, be sure to deallocate it when the memory is no longer needed.

See Also


int ossConvertOctetToTimeStamp(OssGlobal *world, unsigned char *oct_ts, char **pstr_ts);

Converts a null-terminated input string formatted as "'xx...xx'H" into a human-readable timestamp format, YYYYMMDDhhmmss[+-]hhmm.

Arguments

world
Pointer to the OssGlobal variable.
oct_ts
References a string formatted as "'xx...xx'H" that will be converted.
pstr_ts
Points to the location where the address of the resulting timestamp string should be stored.

Return Value

If successful, it returns zero. Otherwise, it returns one of the following error codes:

  • BAD_ARG - bad input argument.
  • BAD_TIME - the TIME type contains a value that is out of range.
  • OUT_MEMORY - no memory is allocated when the function allocates memory for the output string.

Remarks

When pstr_ts points to NULL, the function allocates memory for the output string.

Example

ossConvertOctetToTimeStamp() converts the string '1507061432002B0600'H into output as follows:

20150706143200+0600

See Also

ossPrintOctetAsTimeStamp()


int ossConvertTBCDStringToOctet (OssGlobal *world, char *TBCD_str, unsigned int str_len, unsigned char **oct_str, unsigned int *length);

Converts a TBCD string value into an OCTET STRING type value. The function was added in version 10.2.0.

Arguments

world
Pointer to the OssGlobal variable.
TBCD_str
Points to the null-terminated TBCD string value.
str_len
The length of the TBCD_str value.
oct_str
Points to the address of the buffer where the resulting OCTET STRING type value is stored.
length
Points to the length of the OCTET STRING value.

Return Value

The ossConvertTBCDStringToOctet() function returns an integer. When conversion succeeds, a value of zero is returned. When either world, oct_str, or TBCD_str is a NULL pointer, the function returns the BAD_ARG enumerator. When the input data contains invalid characters, a value of DATA_ERROR is returned. When ossGetMemory() cannot allocate memory for the output string, a value of OUT_MEMORY is returned.

Example

	OssGlobal    	w, *world = &w;
	char   		*tbcd_str = "52901*a2c";
     	unsigned char   *buf = NULL;
     	unsigned int    os_len;
	int          	err;

	. . . . 
    	ossPrint(world, "Source TBCD string: %s\n", tbcd_str);
    	ossPrint(world, "Call ossConvertTBCDStringToOctet()... ");
    	err = ossConvertTBCDStringToOctet(world, tbcd_str, strlen(tbcd_str), &buf, &os_len);
    	if (err == 0) {
        ossPrint(world, "conversion succeeded.\n");
        ossPrint(world, "Resulting octet string: \n");
        ossPrintHex(world, (char *)buf, os_len);
        ossFreeMemory(world, buf);
    	} else {
        ossPrint(world, "conversion failed with return code %d\n", err);
    	}
	. . . .    

ossConvertTBCDStringToOctet() sample output:

Source TBCD string: 52901*a2c
Call ossConvertTBCDStringToOctet()... conversion succeeded.
Resulting octet string: 2509A12C FE

Remarks

If oct_str points to NULL, the function will automatically allocate space for the output string. When you preallocate memory for the output string, you must set the oct_str pointer to reference the beginning of your memory block.

When you use the ossConvertTBCDStringToOctet()function to allocate memory, you must call the ossFreeMemory() function and pass the returned oct_str pointer to it when your application no longer needs the output string. If you allocated memory for the output string, be sure to deallocate it when the memory is no longer needed.

See Also


int ossCpyValue (OssGlobal *world, int pdunum, void *source, void **destination);

Allocates memory and copies unencoded PDUs into identical structures. To deallocate the destination PDU after using it, use ossFreePDU().

Arguments

world
Pointer to the OssGlobal variable.
pdunum
INTEGER containing a compiler-generated PDU number.
source
Address of the PDU which contains the data to be copied.
destination
Pointer referencing the copied data. If a preallocated buffer is not provided for the new copy, *destination must be set to NULL. If a preallocated buffer is provided, the length of the buffer must be set using the ossSetDecodingLength() function.

Return Value

If successful, it returns zero. Otherwise, it returns an error code:

  • if value1 or value2 is NULL, returns BAD_ARG
  • if pdunum is invalid, returns PDU_RANGE
  • for TOED compiled without the OSS_COPY_VALUE defined, returns UNIMPLEMENTED

Example

OssGlobal w, *world = &w;
MyASN1DataType *decodedData, *newValue=NULL;
int rc;
  . . .
ossCpyValue(world, MyASN1DataType_PDU, decodedData, &newValue);
  . . .
ossFreePDU(world, MyASN1DataType_PDU, newValue);

Remarks

To support this function, TOED builds must be C-compiled with the OSS_COPY_VALUE defined.

See Also


int ossDotValToEncodedOid(OssGlobal *world, const char *dotOID, OssEncodedOID *encodedOID);
int ossDotValToEncodedRelOid(OssGlobal *world, const char *dotOID, OssEncodedOID *encodedOID);

These functions convert an OBJECT IDENTIFIER or a RELATIVE-OID dotted notation string into the ENCODED format, which is required before passing Object Identifiers to the encoder. The dotted notation is a string of numbers separated by periods ("1.2.3.4.5").

The ENCODED representation has the following format:

typedef struct {
  unsigned short length;
  unsigned char *value;
} OssEncodedOID;

value is a pointer to a byte array containing the encoded data, as BER value, without tag and length: OBJECT IDENTIFIER "1.2.3.4.5" is stored as: 0x2A, 0x03, 0x04, 0x05).

length is the size of the array in bytes: 4, in this case.

Arguments

world
Pointer to the OssGlobal variable.
dotID
String pointer containing an OBJECT IDENTIFIER or RELATIVE-OID in the form "{X.Y.Z}" (including quotes).
encodedOID
Output structure for the ENCODED value. To allocate the output memory, set the length and value fields to NULL and 0, respectively. To deallocate it, use ossFreeBuf(). Otherwise, preallocate the output buffer to fit the value, and initialize the fields accordingly.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal world;
OssBuf encodedData;
OssEncodedOID encodedOID;
ObjectID OIDvalue;
int rc, pdunum = 1;
char *dotValue = "1.2.3.418446744073709551615.456";
  . . .
encodedOID.value = NULL;
encodedOID.length = 0;
rc = ossDotValToEncodedOid(&world, dotValue, &encodedOID);
if (rc) {
  ossPrint(world, "Call to ossDotValToEncodedOid() failed: %d\n", rc);
return rc;
}
OIDvalue.length = encodedOID.length;
OIDvalue.value = encodedOID.value;
ossEncode(&world, pdunum, &OIDvalue, &encodedData);

See Also


int ossDupWorld(OssGlobal *original_world, OssGlobal *duplicate_world);

Creates a copy of an instance of the OssGlobal structure initialized with the ossinit() | ossWinit() function.

A call to ossDupWorld() incurs a lower overhead compared to a new call to ossinit() | ossWinit(). When using this function in multi-threaded applications, you will not have to call ossinit() | ossWinit() for each new thread because the parent code calls it once. Then, each new thread calls ossDupWorld() upon start-up to obtain its own copy of OssGlobal. The duplicate copy of OssGlobal inherits encoding rules, encoding/decoding flags, and other runtime settings from the original. Before termination, each thread must call ossterm(), ossUterm(), ossWterm() to free the resources connected to its copy of the OssGlobal variable.

Arguments

original_world
Points to the initialized global OSS environment variable to be copied.
duplicate_world
Address of the OssGlobal structure containing the duplicate copy.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Remarks

Important: In the memory handle allocation mode, a call to ossDupWorld() does not preserve the currently installed memory handle in a copied world. This is done to avoid simultaneous write access to the handle when trying to allocate memory in different threads. To use memory handle allocation mode in a multithreading application, you must manually create different memory handles for each OSS global environment variable.

Warning: When using dynamically linked libraries (DLLs), make sure you do not call ossterm() | ossWterm() | ossUterm on the original instance of OssGlobal while using duplicate copies of the OssGlobal variable. Otherwise, DLLs that were loaded before the call to ossDupWorld() is unloaded from memory, causing the application to crash on any attempt of a copy of OssGlobal. Make sure you call ossterm() | ossUterm() | ossWterm() on the copied OssGlobal before it is called on the original OssGlobal variable.

See Also

ossGetOssGlobalSize()


int ossDurationEndPointRecIntervalToString(
          OssGlobal *world, ossDuration *dur, ossTimePoint *end, int rec, char **dest);
int ossDurationEndPointIntervalToString(
          OssGlobal *world, ossDuration *dur, ossTimePoint *end, char **dest);

These functions construct the string representation of an ISO 8601 [recurring] time interval in the form of a [recurring] duration-end pair from its individual components. Use them when the TIME type has a Property settings constraint applied, the Basic property is set to [Rec-]Interval and Interval-type is set to "DE".

For newly constructed time values, the ossGetTimeKind() function returns oss_tk_DurationEndPointRecInterval | oss_tk_DurationEndPointInterval .

Arguments

world
Pointer to the OssGlobal variable.
dur
Pointer to the duration value of the time interval.
end
Pointer to the end point value of the time interval.
rec
Number of recurrences.
dest
Output string representation of the ISO 8601 time interval. If *dest is NULL, the function will automatically allocate the output string (to deallocate it, call ossFreeMemory()) or a pointer to the memory that you allocated.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w, *world = &w;
int rc, rec = 0;
ossTimePoint end;
ossDuration dur;
char *result = NULL;
  . . . 
ossStringToDurationEndPointRecInterval(world,
R/P1Y4M20D/1985-04-12T23:20:50", &dur, &end, &rec);
dur.bit_mask |= OSS_de_hours_present;
dur.hours = 1;
dur.bit_mask |= OSS_de_minutes_present;
dur.minutes = 30;
rec = 2;
dur.bit_mask &= ~OSS_de_years_present;
ossDurationEndPointRecIntervalToString(world, &dur, &end, rec, &result);
ossPrint(world, "Resulting string: %s\n", result);
ossFreeBuf(world, result);

Prints:

Time interval to string conversion succeeded. 				
Resulting string: R2/P4M20DT1H30M/1985-04-12T23:20:50

See Also

ossStringToDurationEndPointRecInterval() | ossStringToDurationEndPointInterval()


int ossDurationRecIntervalToString(
            OssGlobal *world, ossDuration *inp, int rec, char **dest);
int ossDurationIntervalToString(
            OssGlobal *world, ossDuration *inp, char **dest);

These functions construct the string representation of an ISO 8601 [recurring] time interval in the form of a duration from its individual components. Use them when the TIME type has a Property settings constraint applied, the Basic property is set to [Rec-]Interval and Interval type is set to "D".

For newly constructed time values, the ossGetTimeKind() function returns oss_tk_DurationRecInterval | oss_tk_DurationInterval .

Arguments

world
Pointer to the OssGlobal variable.
inp
Pointer to the duration value of the time interval.
rec
Number of recurrences.
dest
Output string representation of the ISO 8601 time interval. If *dest is NULL, the function will automatically allocate the output string (to deallocate it, call ossFreeMemory()) or a pointer to the memory allocated by you.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w, *world = &w;
int rc, rec = 0;
ossDuration dur;
char *result = NULL;
  . . . 
rc = ossStringToDurationRecInterval(world, "R10/P1Y4M20DT30M", &dur, &rec);
dur.bit_mask |= OSS_de_seconds_present;
dur.seconds = 45;
ossDurationRecIntervalToString(world, &dur, rec *2, &result);
ossPrint(world, "Resulting string: %s\n", result);
ossFreeBuf(world, result);

Prints:

Resulting string: R20/P1Y4M20DT30M45S

See Also

ossStringToDurationRecInterval() | ossStringToDurationInterval()


int ossConvertData(OssGlobal *world,
             OssBuf *fromData, unsigned int fromFormat,
             OssBuf *toData, unsigned int toFormat);

Converts data to binary, hexadecimal, and BASE64 formats. To convert data, specify the corresponding format identifiers: OSS_BIN_DATA, OSS_HEX_DATA, OSS_BASE64_DATA.

If the corresponding memory manager is in use, conversion is possible not only in memory but also to and from files, sockets and OSAK-buffers.

Arguments

world
Pointer to the OssGlobal variable.
fromData
Address of the input data OssBuf. The value and the length fields specify the memory location and length of the data in bytes. If the input source is a file, OssBug.length indicates the number of bytes from the beginning of the file to be converted. To convert the entire file, set it to 0. If the input source is a socket, OssBug.length must be set to a non-zero value.
fromFormat
Input data format.
toData
Pointer to the output data OssBuf. To allow automatic output buffer allocation, set OssBuf.length and OssBuf.value to NULL. To manually preallocate memory, set OssBuf.length and OssBuf.value to reference the allocated memory.
toFormat
Output data format.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

/* OSS_BIN_DATA -> OSS_HEX_DATA conversion from file to memory */
OssGlobal w, *world = &w;
OssBuf fromData; /* input data */
OssBuf toData; /* output data */
int retcode;
if ((retcode = ossinit(world, control_table))) 
{
ossPrint(NULL, "Ossinit() returned %d\n", retcode);
return retcode;
}
#ifdef DLL_LINKAGE
if (!ossLoadMemoryManager(world, OSS_FILE_MEMMGR, NULL)) 
{
ossPrint(world, "Memory manager linkage failed.\n");
ossterm(world);
return 1;
}
#endif /* DLL */
  . . .
				
/* Initialize the input buffer as a file */
fromData.value = 
(unsigned char *)ossMarkObj(world, OSS_FILE, (void *)"input.bin");
fromData.length = 0; /* conversion of all bytes from the file */
				
/* Initialize the output buffer as a dynamic memory */
toData.value = NULL;
toData.length = 0;

if (ossConvertData(world, &fromData, OSS_BIN_DATA,
&toData, OSS_HEX_DATA)) 
{
/* an error occurred, print errmsg */
ossPrint(world, "%s\n", ossGetErrMsg(world));
ossterm(world); /* Free up allocated resources */
return 1;
}
ossUnmarkObj(world, fromData.value);
  . . .
/* Free up the allocated data buffer */
ossFreeBuf(world, toData.value);
  . . .
ossterm(world);

Remarks

If the input format is OSS_HEX_DATA or OSS_BASE64_DATA, the input data is checked for conformance to the format, and whitespace is ignored. If the number of digits in the input hexadecimal data is odd, a trailing '0' is added by default. For example, 'FF F' is treated as 'FF F0'.

See Also

ossFreeBuf()


int ossGenTimeStringToCalTime(OssGlobal *world, char *in, time_t *out);
int ossUTCTimeStringToCalTime(OssGlobal *world, char *in, time_t *out);

Converts GeneralizedTime or UTCTime from ASN.1 value string into a time_t standard ANSI type (calendar time) value.

Arguments

world
Pointer to the OssGlobal variable.
in
Time represented as ASN.1 value string.
out
Address of an output calendar time value.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

See ossCalTimeToGenTimeString().

See Also


int ossGenTimeStructToCalTime(OssGlobal *world, GeneralizedTime *in, time_t *out);
int ossUTCTimeStructToCalTime(OssGlobal *world, UTCTime *in, time_t *out);

Converts a GeneralizedTime or UTCTime value into a time_t standard ANSI type (UTC calendar time value).

Arguments

world
Pointer to the OssGlobal variable.
in
Address of the GeneralizedTime or UTCTime value.
out
Address of an output calendar time value.

Return Value

If successful, it returns zero. Otherwise, it returns BAD_ARG or BAD_TIME.

Example

See ossCalTimeToGenTimeString()

See Also


int ossEncodedOidToAsnVal(OssGlobal *world, const OssEncodedOID *encodedOID, OssBuf *valOID);
int ossEncodedRelOidToAsnVal(OssGlobal *world, const OssEncodedOID *encodedOID, OssBuf *valOID);

These functions convert an OBJECT IDENTIFIER or a RELATIVE-OID value from the ENCODED representation into the value notation representation. They are especially useful for printing Object Identifier values received from the decoder. The value notation form is a string of whitespace-separated numbers enclosed in braces (for example, a RELATIVE-OID can be represented as "{3 4 5}").

The ENCODED representation has the following format:

typedef struct {
  unsigned short length;
  unsigned char *value;
} OssEncodedOID;

value is a pointer to a byte array containing the encoded data, as BER value, without tag and length, for example, RELATIVE-OID "{3 4 5}" is stored as: 0x03, 0x04, 0x05).

length is the size of the array in bytes: 3, in this case.

Arguments

world
Pointer to the OssGlobal variable.
encodedOID
Pointer to the ENCODED value the Object Identifier to be converted.
valOID
Address of an OssBuf structure to return the Object Identified in the form "{X Y Z}" (including quotes). To instruct the function to allocate the output memory, set the length and value fields of the structure to NULL and 0, respectively. To deallocate it, use ossFreeBuf(). Otherwise, preallocate the output buffer to fit the value (make sure you allocate an extra byte for the terminating NULL character) and initialize the fields accordingly.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal w;
OssBuf encodedData;
OssBuf myAsnValOid;
Msg *decodedData = NULL;
  . . .
ossDecode(&w, &myPduNum, &encodedData, (void **)&decodedData);
myAsnValOid.value = NULL;
myAsnValOid.length = 0;
ossEncodedRelOidToAsnVal(&w, (OssEncodedOID*)&decodedData->tcpId, &myAsnValOid);
ossPrint(&w, "AsnVal: %s\n", myAsnValOid.value);
  . . . 
ossFreeBuf(&w, myAsnValOid.value);

See Also


int ossEncodedOidToDotVal(OssGlobal *world, const OssEncodedOID *encodedOID, OssBuf *dotOID);
int ossEncodedRelOidToDotVal(OssGlobal *world, const OssEncodedOID *encodedOID, OssBuf *dotOID);

These functions convert an OBJECT IDENTIFIER or a RELATIVE-OID value from the ENCODED representation into the dotted notation. They are especially useful when printing Object Identifier values received from the decoder. The dotted notation is a string of numbers separated by periods (for example, a RELATIVE_OID can be represented as "3.4.5").

The ENCODED representation has the following format:

typedef struct {
  unsigned short length;
  unsigned char *value;
} OssEncodedOID;

value is a pointer to a byte array containing the encoded data, as BER value, without tag and length, for example, RELATIVE-OID "3.4.5" is stored as: 0x03, 0x04, 0x05)

length is the size of the array in bytes: 3, in this case.

Arguments

world
Pointer to the OssGlobal variable.
encodedOID
Pointer to the ENCODED value of the Object Identifier to be converted.
dotOID
Address of OssBuf structure to return the Object Identified in the form "X.Y.Z". To instruct the function to allocate the output memory, set the length and value fields of the structure to NULL and 0, respectively. To deallocate it, use the ossFreeBuf(). Otherwise, preallocate the output buffer to fit the value (make sure you allocate an extra byte for the terminating NULL character) and initialize the fields accordingly.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

See ossEncodedOidToAsnVal()

See Also


int ossGeneralizedTimeToInts(OssGlobal *world, char *timeString,
             unsigned int *year, unsigned int *month,
             unsigned int *day, unsigned int *hour, unsigned int *minute, unsigned int *second,
             unsigned int *fraction, unsigned short *precision, int *local_utc_mindiff);
int ossGeneralizedTimeToShorts(OssGlobal *world, char *timeString,
             unsigned short *year, unsigned short *month,
             unsigned short *day, unsigned short *hour, unsigned short *minute, unsigned short *second,
             unsigned short *fraction, unsigned short *precision, short *local_utc_mindiff);
int ossUTCTimeToInts(OssGlobal *world, char *timeString,
             unsigned int *year, unsigned int *month,
             unsigned int *day, unsigned int *hour,
             unsigned int *minute, unsigned int *second,
             int *utc_mindiff);
int ossUTCTimeToShorts(OssGlobal *world, char *timeString,
             unsigned short *year, unsigned short *month,
             unsigned short *day, unsigned short *hour, unsigned short *minute,
             unsigned short *second, short *utc_mindiff);

These functions parse the input time represented as ASN.1 value string to retrieve the field values of a GeneralizedTime or UTCTime type.

Arguments

world
Pointer to the OssGlobal variable.
timeString
Time represented as ASN.1 value string.
year/month/.../second
The corresponding fields of GeneralizedTime or UTCTime.
fraction
Fractional part of the seconds field (for example, milliseconds).
precision
Number of digits in the fractional part of the seconds field (for example: number of digits found after the decimal point in timeString).
local_utc_mindiff
The positive or negative minute differential between local time and GMT, or set to 0 for the local time, and to 1 for UTC time.

Return Value

If successful, it returns zero. Otherwise, it returns BAD_TIME. If the UTC time format is not enabled while using DER encoding rules, it returns BAD_TIME.

Example

UTCTime myTime;
OssGlobal w, *world = &w;
char gen_timeString[40];
unsigned short fraction_precision=0;
unsigned int fraction, year, month, day, hour, minute, second;
int mindiff;
  . . .
myTime.year=2001; myTime.month=8; myTime.day = 23; myTime.hour = 12;
myTime.minute = 33; myTime.second=27; myTime.mindiff = -300;
				
ossIntsToGeneralizedTime(world, myTime.year, myTime.month, myTime.day, myTime.hour, myTime.minute, myTime.second, 258, 3, 1, gen_timeString);
ossPrint(world, "Generalized TimeString: %s \n",gen_timeString);
				
ossGeneralizedTimeToInts(world, gen_timeString,
&year, &month, &day, &hour, &minute, &second,
&fraction, &fraction_precision, &mindiff);
ossPrint(world, "Year: %d\nMonth: %d\nDay: %d\nHour: %d\nMinute: %d\n\

Second: %d\nMindiff: %d\nFraction: %d\nFraction_Prec: %d\nReturn code: %d\n", 
year, month, day, hour, minute, second, mindiff, fraction, fraction_precision, retcode);

Prints

Generalized TimeString: 20010823123327.258Z
Year: 2001
Month: 8
Day: 23
Hour: 12
Minute: 33
Second: 27
Mindiff: 1
Fraction: 258
Fraction_Prec: 3
Return code: 0

Remarks

These functions are implemented in SOED (for example, soeddefa.lib).

See Also

ossIntsToGeneralizedTime() | ossIntsToUTCTime()


int ossPartialDecode(OssGlobal *world, int *pdunum, OssBuf *input, void **output);

Performs the partial decoding. For general information about partial decoding, see the Partial Decoding section.

Arguments

world
Pointer to the OssGlobal variable.
pdunum
Pointer to an integer type containing the compiler-assigned PDU number for the compiler-generated data structure for decoding.
input
Address of the OssBuf variable whose value field references the BER, DER, PER (aligned or unaligned), OER, or COER encoding to be decoded and whose length field holds the length in bytes of this encoding.
output
Address of a pointer to the memory block that temporarily holds the decoded fields while decoding.

Remarks

If NULL or the address of a NULL pointer is passed as the fourth argument, the decoder's memory manager will automatically allocate enough memory to hold the decoder data. On the other hand, if you preallocate a buffer for the decoder data and pass the address of a pointer that references your preallocated buffer, the decoder uses the provided buffer and works faster. Note, however, that after preallocating an output buffer and before calling the decoder each time, you must call the ossSetDecodingLength() function to set the length of the allocated buffer.

If a decoding error occurs and the decoding buffer was preallocated, the fields of the preallocated output area could be updated, therefore the contents are unpredictable. However, if you instructed the decoder to allocate the memory for the output data (by passing an address to a NULL pointer as a fourth parameter), the decoder removes any temporary memory allocated before exiting and its output will still point to the NULL pointer.

Return Value

The ossPartialDecode() function returns an integer. If the input was successfully decoded, a value of zero is returned; otherwise, a non-zero value is returned. For more information about the return codes, see the ASN.1/C API Return Codes section. Upon failure, use the ossGetErrMsg() function to determine the cause of the problem.

During partial decoding, when the ossPartialDecode() function encounters a field to which the OSS.DataCallback or OSS.InfoCallback compiler directive is applied, it calls the specified callback function (provided by the user).

NOTE: The prototypes of the callback functions are incorporated into the generated header file.

Here is the data callback function prototype:

int my_callback(OssGlobal *world, long offset, long length, unsigned int flags, Tvalue *value);

Arguments

world
Pointer to the OssGlobal structure.
offset
The offset (in bytes) of the field.
length
The length (in bytes) of the field encoding.
flags
Indicates situations where it would not be possible to isolate the value using offset and length, that is, where it would be difficult and error-prone for you to try to modify the value in-place. Each flag is described below.
value
A pointer to the decoded value.

The world, offset, length, and flags parameters are the same for all callback functions. The value parameter points to the decoded value of the field to which the directive is applied. Its C-type varies depending on the ASN.1 type and the C representation of the field.

Value Description
OSS_ENCODING_UNDEFINED
Is returned whenever the field in question is encoded using bit-oriented rules (PER, UPER, CPER, CUPER), and not octet-oriented rules (BER, DER, OER, COER). This is of consequence if you intend to modify values in-place, since offset and length alone will not isolate the value. Modifying the value when this flag is returned is not recommended.
OSS_COMPLEX_ENCODING
Is returned whenever a BER field is fragmented. Some types, for example, OCTET STRINGs, may be broken into fragments where each fragment has a separate offset and length. This makes it difficult to discern what the value is, and so modifying the value when this flag is returned is not recommended.

To instruct the decoder whether to stop or continue decoding the message, use one of the return codes of your callback function.

  • If the function returns OSS_SKIP_TO_PDU_END, the decoder will skip the remaining fields until it reaches the end of the message. However, although this process is faster than the typical decoding, the speed depends on the encoding rules and on the message structure.
  • If the function returns OSS_CONTINUE_DECODING, the decoder will continue to partially decode the message. That is, if a subsequent field is associated with a callback function, it will be called.

Any other return code from the callback function signals to the decoder a decoding error, in which case the decoder executes a longjmp() and ossPartialDecode() returns the return code it received from the callback function. However, returning via longjmp() is often slower than using OSS_SKIP_TO_PDU_END to skip to the end.

Example

--<OSS.DataCallback BCAS.BBCard.age "myFunc">--

BCAS DEFINITIONS ::= BEGIN

CareerEntry ::= SEQUENCE {
   from  INTEGER (0..MAX),
   to    INTEGER (0..MAX) OPTIONAL, 
   team  VisibleString (SIZE (1..255))
}

BBCard ::= SEQUENCE {
   name      VisibleString (SIZE(1..64)),
   age       INTEGER (1..100),
   position  VisibleString (SIZE (1..64)),
   career    SEQUENCE OF CareerEntry
}
END

The compiler generates the following callback function prototype:

/* myFunc is user-defined data callback function for ASN.1 item(s)
 * BCAS.BBCard.age */

extern int myFunc(OssGlobal *_g, long offset, long length,
unsigned int flags, unsigned short * value);

The decoded value pointed to by the last parameter is available only in the callback function.

The decoder reuses the memory allocated for the value after the callback function returns. Therefore, the callback function code should store the decoded field value for future use, if necessary. Reusing memory like this significantly reduces the amount needed for decoding. For example, if the DataCallback directive is applied to an element of a SEQUENCE OF type, the decoder will not allocate more memory than needed for one element. Decoding speed is improved if you use a preallocated buffer for partial decoding.

Here is the info callback function prototype:

int my_callback(OssGlobal *world, char * fname, unsigned int flags);

Arguments

world
Pointer to the OssGlobal structure.
fname
The field name.
flags
The least significant bit of the flags value is set to 1 if the callback function is called before decoding the field; otherwise, it is set to 0 (after decoding the field). The other bits of flags are reserved for future use.

The return codes are the same as the ones for the data callback functions.

To pass data between the application and the callback functions or between callback functions calls, use the userVar (void *) field within the ossGlobal structure. If the data to be passed fits the pointer size, it can be directly stored in the field. Otherwise, the field can store a pointer to the memory block that contains the data.

When the OSS.DataCallback directive is applied to a field, the compiler generates code that fully decodes the field, and it passes the address of the decoded value to the specified callback function. Otherwise, the compiler generates code to skip the field.

The method used for skipping a field depends upon the field and upon the encoding rules employed, as follows:

  • In the case of definite length BER, the decoder can simply jump over the field.
  • For PER the decoder cannot always be certain where the field ends without decoding it, and so the decoder often decodes the field and then discards the decoding.

In any case, the pointer to the current position is advanced to the subsequent field.

NOTE: During partial decoding, when the decoder is able to skip a field by jumping over it, it does not check the field encoding for adherence to the encoding rules.

See Also


int ossSetCompatibilityFlags(OssGlobal *world, unsigned long flags);
unsigned long ossGetCompatibilityFlags(OssGlobal *world);

Sets or gets backward compatibility flags that affect the behavior of the ossEncode() and ossDecode() functions.

NOTE: OSS does not guarantee compatibility between different versions of the ASN.1 Tools released more than 10 years apart.

Arguments

world
Pointer to the OssGlobal variable.
flags
Bitmask of the flags listed in the table below.
Flag Description
OSS_ADD_ZERO_SECONDS_TO_XML_ENCODING_OF_NULLTERM_TIME (E)
Available for the LEAN/SOED/TOED XER and LEAN/TOED E-XER encoders. Forces the encoder to display a zero seconds component when encoding GeneralizedTime and UTCTime type values that have the NULLTERM representation.
OSS_ALLOW_ABSENT_OR_BAD_SECONDS
Available for CER/DER SOED and DER TOED decoders. Instructs the decoder to restore old behavior, and accept non-standard encodings. Starting with version 8.1.2, the decoder reports an error if the encoding of a UTCTime or GeneralizedTime type does not satisfy the restrictions on BER employed by both CER and DER. For example, when seconds digits are absent, or trailing zeroes are present in a fractional part.
OSS_ALLOW_MISPLACED_EXTENSION_FIELDS
Available for the SOED/LED BER decoder. Instructs the decoder in relaySafe mode to accept an unknown extension field, placed after the additional root fields in the input encoding. Otherwise, the decoder issues the error message "D0047E: Tag not recognized".
OSS_ALLOW_NON_NR3_DER_REAL
Available for the DER, CER and PER encoder. Instructs the encoder to skip NR3 normalization of decimal REAL type values.
OSS_ALLOW_NULL_IN_TIME
Available for the BER Time-optimized decoder. The ossDecode() function will silently ignore superfluous trailing NULL octets in the encoding of a value of a GeneralizedTime type with the NULLTERM representation. Otherwise, an error is issued.
OSS_ALLOW_TIME_DIFFERENTIAL_IN_UTC_TIME
Available for the DER encoder. UTCTime values that are incorrectly encoded (with a non-zero time differential) will be successfully decoded.
OSS_ALLOW_ZERO_LENGTH_EXTENSIONS
Available for the PER decoder version 6.1.3. The ossDecode() function will silently ignore zero-length extension fields in a PER encoding. Starting with version 6.1.4, unless STRICT_ENCODING_DECODING_RULES is specified (via ossSetDecodingFlags() or ossSetFlags()), the ossDecode() function silently ignores zero-length extension fields. Otherwise, the ossDecode() function issues an error when processing PER encodings with zero-length extension fields.
OSS_ALLOW_ZERO_LENGTH_OPENTYPE_STRINGS
Available for PER SOED. Instructs the decoder to restore old behavior and accept non-standard encodings in which extension additions are encoded as zero-length opentype values. Starting with version 4.2, unless the extension addition is a NULL type, the encoder reports an error when the encoding of an extension addition occupies 0 bits.
OSS_AUTO_DETECT_PDU_NUMBER
Available for the SOED runtime. Instructs the decoder to restore the previous behavior and attempt to determine the PDU number even when a non-zero number is passed. Starting with version 10.2, the SOED BER decoder attempts to determine the PDU number from the input encoding only if the zero PDU number was passed to ossDecode().
Note: If -compat autoDetectPDUnumber is specified, the flag is automatically enabled in the generated code.
OSS_EXTENDED_RESTRICTED_KMC_STRING_AS_OCTETS
Available for the PER encoder/decoder. Instructs the encoder/decoder to ignore Permitted Alphabet in extensible KMC string types when the string length exceeds that of the extension root.
OSS_EXTENDED_UNRESTRICTED_CHAR_STRINGS
Available for the PER encoder. Instructs the encoder to encode length determinants (of unknown multiplier character strings with size constraints) as constrained INTEGERs. Also, the character strings are encoded as values of extensible types (if the extension marker "..." is used in the ASN.1 syntax).
OSS_INTERVAL_FRACTION_1_999
Available for the PER runtime. The use of this flag causes the encoding of a DURATION-INTERVAL/fractionial value as INTEGER (1..999, ..., 1000..MAX) instead of INTEGER (0..999, ..., 1000..MAX).
OSS_KEEP_MEMORY_MANAGER_TEMPORARY_FILES
Available for socket and file memory managers. Instructs socket and file memory managers to delete temporary files automatically created for marked objects only if ossFreePDU() is called for the PDU stored in each file. Starting with version 8.3, these files are deleted when ossterm() is called.
OSS_NO_DETAIL_MM_ERROR_CODES
Available for the SOED runtime. Prior to version 10.0, when errors occurred in the OSS Socket and File Memory Managers, OSS API functions returned the common error code FATAL_ERROR (18) and the following message: x0087S: Undefined memory-management error #N. Starting with version 10.0, more error codes and messages are returned in this case. This flag restores the previous behavior.
OSS_OLD_UTF8_CHECK
Available for the LEAN/SOED/TOED runtime. Starting with version 10.6, the runtimes check UTF8 characters more thoroughly: the high and low surrogate halves used by UTF-16 (U+D800 through U+DFFF) and code points that are not encodable by UTF-16 (those following U+10FFFF) are considered illegal Unicode values, and their UTF-8 encoding is treated as an invalid byte sequence. The 0xfffe and 0xffff UTF-8 encoding codes are also treated as an invalid byte sequence. This flag restores pre-10.6 runtime behavior.
OSS_PACK_WIDE_STRINGS
Available for PER. Wide string characters with permitted alphabet constraints are encoded relative to the zero value of the lowest Cell in the permitted alphabet and not to the lowest value in the Cell. For example:
A ::= BMPString 
(FROM({0,0,30,32}..{0,0,30,127}))
a A ::= {0,0,30,64}
Value a is encoded as 0x0140 instead of 0x0120 in aligned PER, as for the permitted alphabet:
FROM({0,0,30,0}..{0,0,30,127}
OSS_PER_ALLOW_TRAILING_ZEROS
Available for PER SOED. Provides compatibility with pre-8.5 versions. Starting with version 8.5, the encoder strips zero trailing bits from the encoding of a BITSTRING with named bits according to Clause 16.2 of X.691. Previously, such bits were encoded.
OSS_PER_NULLTERM_TIME_8BIT_CHARS
Available for the PER encoder/decoder. Instructs the encoder/decoder to treat the Unaligned PER encoding of UTCTime and GeneralizedTime types in the NULLTERM C-representation as using 8 bits per character, the same as the Aligned PER encoding.
OSS_PER_VISIBLE_EXCEPTIONS
Available for the PER encoder/decoder. Instructs the encoder/decoder to treat the EXCEPT constraint as PER-visible.
OSS_TRUNCATE_0_SECONDS_FROM_GENERALIZED_TIME
Available for the SOED BER, DER, CER, and PER encoder. Trailing zeros placed after the seconds field in GeneralizedTime type encodings is truncated (for example, 1998120311235500 is truncated to 19981293112355).
OSS_TRUNCATE_0_SECONDS_FROM_UTC_TIME
Available for SOED BER, DER, CER, and PER encoder. Trailing zeros placed after the seconds field in UTCTime type encodings are truncated (for example, 98120311235500Z is truncated to 981203112355Z).
OSS_USE_TYPE_IDENTIFICATION_ATTRIBUTE_FOR_UNION
Available for the SOED/LED runtime. Starting with version 9.0, the OSS SOED/LED E-XER encoders no longer generate a type identification attribute for a CHOICE type with a USE-UNION encoding instruction when the final UNTAGGED encoding instruction is applied to the type. This flag instructs the E-XER encoder to restore the previous behavior.
OSS_V412_TIME_AND_WIDE_CHAR_STRINGS
Available for the PER encoder/decoder. The following changes take place:
  • The OSS_PER_ALIGNED flag is considered present and UTCTime and GeneralizedTime types are encoded/decoded accordingly.
  • UTCTime and GeneralizedTime types are handled as size-constrained character strings with the length determinant encoded as a constrained INTEGER.
  • Characters in wide character strings with permitted alphabets are encoded/decoded as indices of the specified permitted alphabets.
OSS_V85_TABLE_CONSTRAINT_FOR_EXTENSIBLE_OBJECT_SETS
Available for the SOED/LED runtime. Starting with version 8.6, the OSS Constraint Checker no longer mishandles table/component relation constraint violations for extensible object sets. The OSS ASN.1 compiler and the OSS runtime support X.681 Annex E.2. That is, constraint violation errors are reported if table/component relation constraints are not satisfied for extensible object sets, and in any of the following situations:
  • The value of a UNIQUE field is found in the object set.
  • The STRICT_CONSTRAINT_CHECKING runtime flag is specified.
  • The OSS_AUTO_ENCODE_WITHOUT_CHECKING_CONSTRAINT encoder flag is not specified.
This flag instructs the constraint checker to restore the previous (pre-8.6) behavior.
OSS_V90_ARRAY_AND_VARYING_SIZE
Available for the SOED runtime. Prior to version 10.0, memory for the decoded values of:
  • size constrained restricted character string types with a VARYING representation
  • size constrained BIT/OCTET string types with a VARYING representation
  • size constrained SEQUENCE OF and SET OF types with an ARRAY representation
was allocated according to the actual value length, not according to the C-type.
In header files, such types are defined using a fixed size array, as illustrated below:
S ::= IA5String (SIZE(0..10)) --<VARYING>--

typedef struct S {
    unsigned short  length;
    char            value[10];
} S;
For example, the value field of the decoded values S ::= "foo" contained 3 bytes, instead of 10.
This flag instructs the SOED decoders to restore the previous (pre-10.0) SOED decoder behavior.

Return Value

If ossSetCompatibilityFlags() is successful, returns zero. Otherwise, returns a non-zero value.

If ossGetCompatibilityFlags() is successful, returns a logical OR of the set compatibility flags. Otherwise, returns a value of -1.

Example

OssGlobal w, *world = &w;
unsigned long compatFlags;
  . . . 
compatFlags = OSS_EXTENDED_UNRESTRICTED_CHAR_STRINGS;
compatFlags |= OSS_ALLOW_TIME_DIFFERENTIAL_IN_UTC_TIME;
ossSetCompatibilityFlags(world, compatFlags);
compatFlags = ossGetCompatibilityFlags(world);
if(compatFlags & OSS_EXTENDED_UNRESTRICTED_CHAR_STRINGS)
ossPrint(world, "Extended Unrestricted Char Strings in use.\n");

int ossGetConstructedNestingLimit(OssGlobal *world);
int ossSetConstructedNestingLimit(OssGlobal *world, int level);

Sets or gets a definite limit on the number of levels of nesting a constructed string encoding can have. This limit helps prevent intentional or unintentional nested overloading of constructed string encodings.

Arguments

world
Pointer to the OssGlobal variable.
level
Indicates the maximum nesting level allowed when processing a constructed string encoding. The default maximum nesting level value is 10. To disable nesting level, set the level to 0.

Return Value

If ossGetConstructedNestingLimit() is successful, returns the nesting level limit of constructed string encodings. Otherwise, returns -1.

If ossSetConstructedNestingLimit() is successful, returns 0. Otherwise, returns a non-zero error.

See Also

ossSetSeqSetNestingLimit() | ossGetSeqSetNestingLimit()


int ossGetExtensionAddition(struct ossGlobal *world, void *ext, unsigned int extNum, OssBuf *outBuf);

Retrieves the encodings of extension addition elements via their index contained in the ossExtensions structure upon decoding a PDU with unrecognized extensions. The ossExtensions structure is generated in the representation of SET or SEQUENCE types when the relaySafe option is specified.

Arguments

world
Pointer to the OssGlobal variable.
ext
Address of the ossUnknownExt field in the decoded PDU.
extNum
Index (starting from 0) of the extension whose value to be retrieved.
outBuf
Output buffer that contains the encoding and length of the extension.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal world;
OssBuf encodedData, extBuf;
Msg *decodedDataPtr = NULL;
  . . .
ossDecode(world, &myPduNum, &encodedData, (void **)&decodedDataPtr);
  . . .
ossGetExtensionAddition(world, decodedDataPtr->ossUnknownExt, 2, &extBuf);
  . . .

void *ossGetInfoObject(OssGlobal *world, int objSetNumber, void *uniqueValue);

Returns the address of the specified Information Object in an Information Object Set, allowing you to analyze the contents of the object. You can determine the type of value contained in the open type by viewing the OBJECT IDENTIFIER field in the information object. This function is especially useful when you manually decode open types associated with Information Objects. However, using AUTOMATIC_ENCDEC encoder/decoder flag you will not have to manually retrieve open types when encoding and decoding, because they are automatically encoded/decoded with their containing type.

Arguments

world
Pointer to the OssGlobal variable.
objSetNumber
Compiler-generated ID of the Information Object Set (InfoObjSetName_OSET), from which the object is retrieved.
uniqueValue
Address of a unique value of type marked as UNIQUE in the ASN.1 information class definition. This variable is used to uniquely identify the information object.

Return Value

If successful, it returns the address of the specified object. Otherwise, it returns a NULL pointer.

Example

TCIP_CLASS *myInfoObj;
myInfoObj = ossGetInfoObject(world, TCIP_ObjSet_OSET, &cpt_ActivationTime_ID);
ossPrint(world, "Type=%d, Descr=%s\n", myInfoObj->Type, 
myInfoObj->description);

Remarks

When you use TOED with Information Object handling functions, ASN.1-compile your schema with the -autoEncDec and -toed compiler options. Also, to make these functions available at run time, C-compile the generated code file with -DOSS_INFOOBJ_API defined.

Note that for the automatic encoding/decoding of open types with TOED, you cannot use SET OF or SEQUENCE OF types to be referenced by a component relation constraint that is used to determine the base type of the open type.

See Also


void *ossGetInfoObjectSet(OssGlobal *world, int objSetNumber);

Provides access to an Information Object Set when its identification number is given. Once you have retrieved a set, you can traverse it to access all of the contained objects. An Information Object Set is represented as doubly-linked list with each element having the following structure:

typedef struct ObjectSetEntry {
   struct ObjectSetEntry *next;
   void *object;
   struct ObjectSetEntry *prev;
} ObjectSetEntry;

This function returns the first element in the double linked list. To traverse the list, use the next and prev pointers. The prev pointer of the first element is set to NULL and the next pointer of the last element is also set to NULL.

Arguments

world
Pointer to the OssGlobal variable.
objSetNumber
Compiler-generated ID (InfoObjSetName_OSET) of the set that you wish to access.

Return Value

If successful, it returns the address of the first element. Otherwise, it returns a NULL pointer.

Example

TCIP_CLASS *myInfoObj;
ObjectSetEntry *myObjSet;
  . . .
myObjSet = ossGetInfoObjectSet(world, TCIP_ObjSet_OSET);
while(myObjSet != NULL)
{
myInfoObj = (TCIP_CLASS *)myObjSet->object;
ossPrint(world, "Obj Set at: %d, description: %s\n",
myObjSet->object,
myInfoObj->description);
myObjSet = myObjSet->next;
}

Remarks

To continue traverse the object set, call ossGetInfoObjectSet() every time after you add or delete objects.

To use TOED with Information Object handling functions, ASN.1-compile your schema with the -autoEncDec and -toed compiler options. To make these functions available at runtime, C-compile the generated code file with -DOSS_INFOOBJ_API defined.

See Also


int ossGetOssGlobalSize(void);

Returns the number of bytes occupied by the OssGlobal structure.

Remarks

You can also obtain the size of the OssGlobal structure using the C sizeof() function. However, the ossGetOssGlobalSize() function ensures that the size returned at runtime matches the size during build time.

See Also

ossDupWorld()


int ossGetPrintIndent(OssGlobal *world);
void ossSetPrintIndent(OssGlobal *world, int indent_level);

Sets or gets the indentation level which the ossPrintPER() function will use to print out its output.

Arguments

world
Pointer to the OssGlobal variable.
indent_level
Number of tabs to be used for ossPrintPER() for indenting.

Example

OssGlobal w, *world = &w;
  . . . 
ossSetPrintIndent(world, ossGetPrintIndent(wolrd) + 2);
ossPrintPER(world, &pdunum, &encodedData, NULL, 0, NULL);

See Also

ossPrintPER()


int ossSetRuntimeVersion(OssGlobal *world, OssRuntimeVersion version);
int ossGetRuntimeVersion(OssGlobal *world);

Sets or gets the current compatibility mode of SOED. The encoder/decoder simulates the behavior of the specified version. By default, the encoder/decoder emulates the behavior of the current version (OSS_CURRENT_VERSION is implied).

Arguments

world
Pointer to the OssGlobal variable.
version
One of the values described in the table below.
Value Description
OSS_CURRENT_VERSION
Instructs the encoder/decoder to use the current version compatibility mode. This is the default version and includes no compatibility flags.
OSS_VERSION_412
Provides compatibility with pre-4.1.3 encoder/decoder. The enumerator includes the OSS_V412_TIME_AND_WIDE_CHAR_STRINGS compatibility flag.
OSS_VERSION_419
Provides compatibility with pre-4.1.10 encoder/decoder. The enumerator includes the following compatibility flags:
  • OSS_ALLOW_TIME_DIFFERENTIAL_IN_UTC_TIME
  • OSS_ALLOW_ZERO_LENGTH_OPENTYPE_STRINGS
  • OSS_EXTENDED_UNRESTRICTED_CHAR_STRINGS
  • OSS_PACK_WIDE_STRINGS
  • OSS_TRUNCATE_0_FROM_GENERALIZED_TIME
  • OSS_TRUNCATE_0_SECONDS_FROM_UTC_TIME
OSS_VERSION_540
Provides compatibility with the pre-6.0 encoder/decoder. The enumerator includes the OSS_ALLOW_NULL_IN_TIME compatibility flag and all flags below.
OSS_VERSION_811
Provides compatibility with the pre-8.1.2 encoder/decoder. The enumerator includes the OSS_ALLOW_ABSENT_OR_BAD_SECONDS compatibility flag and all flags below.
OSS_VERSION_840
Provides compatibility with the pre-9.0 encoder/decoder. The enumerator includes the OSS_PER_ALLOW_TRAILING_ZEROS compatibility flag.

Example

OssGlobal w, *world = &w;
OssRuntimeVersion rtVersion;
  . . . 
ossSetRuntimeVersion(world, OSS_VERSION_412);
  . . . 
rtVersion = ossGetRuntimeVersion(world);

Remarks

If ossGetRuntimeVersion() returns OSS_CUSTOM_COMPATIBILITY, it means that the encoder/decoder works in a customized compatibility mode of OSS compatibility flags.

See Also

ossSetCompatibilityFlags()


int ossSetSeqSetNestingLimit(OssGlobal *world, int level);
int ossGetSeqSetNestingLimit(OssGlobal *world);

Sets or gets the definite limit for a SEQUENCE, SET, SEQUENCE OF, SET OF, or CHOICE encoding, regarding the number of levels of nesting. It prevents intentional or unintentional nested overloading of complex structured encodings.

Arguments

world
Pointer to the OssGlobal variable.
level
Indicates the maximum nesting level allowed when processing a SEQUENCE, SET, SEQUENCE OF, SET OF, or CHOICE encoding. The default maximum nesting level value is 64. To disable nesting level, set the level to 0.

Return Value

If ossGetSeqSetNestingLimit() is successful, returns the nesting level limit. Otherwise, returns -1.

If ossSetSeqSetNestingLimit() is successful, returns zero. Otherwise, returns a non-zero error.

See Also

ossGetConstructedNestingLimit() | ossSetConstructedNestingLimit()


ossTimeKind ossGetTimeKind(OssGlobal *world, char *str);

Extracts and returns the time kind from a string containing the ISO 8601 time value.

Arguments

world
Pointer to the OssGlobal variable.
str
Pointer to the character string containing the ISO 8601 time value.

Return Value

Returns an ossTimeKind enumeration.

Example

OssGlobal w, *world = &w;
int rc;
ossTimePoint tp;
char *value = "2007-01-04T13:40", *result = NULL;
  . . . 
switch(ossGetTimeKind(world, value)) {
  case oss_tk_TimePoint:
     ossStringToTimePoint(world, value, &tp);
     tp.bit_mask |= OSS_tp_time_diff_present;
     tp.time_diff.hours = 6;
     ossTimePointToString(world, &tp, &result);
     ossPrint(world, "Resulting string: %s\n", result);
     ossFreeBuf(world, result);
     break;
  case oss_tk_BadTime:
     ossPrint(world, "Bad time value.\n");
     break;
  default:
     ossPrint(world, "Unexpected time value.\n");
}

Prints:

Resulting string: 2007-01-04T13:40+06

See Also

Date/Time Conversions


void ossGetUserFieldCpyCmp(OssGlobal *world,
    int (CDECL_ENTRY_FPTR **ossUserFieldCpy)(OssGlobal *world, OpenType *src, OpenType *dest),
    int (CDECL_ENTRY_FPTR **ossUserFieldCmp)(OssGlobal *world, OpenType *data1, OpenType *data2));
void ossSetUserFieldCpyCmp(OssGlobal *world,
    int (CDECL_ENTRY_FPTR *ossUserFieldCpy)(OssGlobal *world, OpenType *src, OpenType *dest),
    int (CDECL_ENTRY_FPTR *ossUserFieldCmp)(OssGlobal *world, OpenType *data1, OpenType *data2));

Sets or gets the user-defined functions for copying or comparing the userField field of the OpenType structure. These functions are automatically called by ossCpyValue() | ossCmpValue() after all open type fields are copied or compared. To disable these calls, call ossSetUserFieldCpyCmp() with the NULL passed for either or both function arguments.

The user-defined copy and compare functions have the following prototypes:

int (CDECL_ENTRY_FPTR *ossUserFieldCpy)(OssGlobal *world, OpenType *src, OpenType *dest);
int (CDECL_ENTRY_FPTR *ossUserFieldCmp)(OssGlobal *world, OpenType *data1, OpenType *data2);

src is the open type source value.

dest is the open type destination value.

When you call the function (*ossUserFieldCpy)(), the open type field userField can be processed according to your specific needs.

Arguments

world
Pointer to the OssGlobal variable.
ossUserFieldCmp
Pointer of a user-defined comparing function.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

If the user-defined compare function (*ossUserFieldCmp)() is successful, returns zero only if the open type structures have identical user field values. A negative value is returned if data1 is less than data2. A positive value is returned if data1 is greater than data2.

Example

OssGlobal w, *world = &w;
Msg myData, myData2;
int CDECL_ENTRY_FPTR cpyUF(OssGlobal *world, OpenType *src, OpenType *dest)
{ /* user-defined OpenType.userField copy function */
  strcpy(dest->userField, src->userField);
  return 0;
}
				
int CDECL_ENTRY_FPTR cmpUF(OssGlobal *world, OpenType *data1, OpenType *data2)
{ /* user-defined OpenType.userField compare function */
  return strcmp(data1->userField, data2->userField);
}
				
int (CDECL_ENTRY_FPTR *curUserFieldCpy)(OssGlobal *world, OpenType *src, OpenType *dest);

int (CDECL_ENTRY_FPTR *curUserFieldCmp)(OssGlobal *world, OpenType *data1, OpenType *data2);
  . . .
myData.tcipType.userField = (char*)malloc(14*sizeof(char));
strcpy(myData.tcipType.userField, "Message Text.");
myData2.tcipType.userField = (char*)malloc(14*sizeof(char));
ossSetUserFieldCpyCmp(world, cpyUF, cmpUF);
ossGetUserFieldCpyCmp(world, &curUserFieldCpy, &curUserFieldCmp);
(curUserFieldCpy)(world, &myData.tcipType, &myData2.tcipType);
if(((curUserFieldCmp)(world, &myData.tcipType, 
&myData2.tcipType)) == 0)
  ossPrint(world, "Open types have identical user fields.\n");
else
  ossPrint(world, "Open types do not have identical user fields.\n")
  . . .
free(myData.tcipType.userField);
free(myData2.tcipType.userField);

void ossSetUserPrint(OssGlobal *world, FILE *stream,
           int (CDECL_ENTRY_FDEF *ossUserPrint)(OssGlobal *world, const char *format, ...));
void ossGetUserPrint(OssGlobal *world, FILE **stream,
           int (DLL_ENTRY_FPTR **ossUserPrint)(OssGlobal *world, const char *format, ...));

Sets or gets an output stream and a user-defined print function for printing out trace information.

Arguments

world
Pointer to the OssGlobal variable.
stream
Output stream to which the output should be written (such as stdout or a file).
ossUserPrint
Function pointer for a user-defined print function with the printf() behavior.

Example

OssBuf encodedData;           /* length and address of encoded data */
int (DLL_ENTRY_FPTR *curUserPrint)(OssGlobal *world, const char *format, ...);
FILE *curStream;
  . . .
ossSetUserPrint(world, stdout, myPrintFunction);
  . . .
 ossGetUserPrint(world, &curStream, &curUserPrint);

Remarks

To change the default print function, manually assign the asn1prnt function pointer in the OssGlobal structure. For example:

world.asn1prnt = myOwnPrintingFunction;

See Also


void ossSetUserVprint(OssGlobal *world, FILE *stream,
           int (DLL_ENTRY_FPTR *ossUserVprintp)(OssGlobal *world, const char *format, va_list ap)); void ossGetUserVprint(OssGlobal *world, FILE **stream,
           int (DLL_ENTRY_FPTR **ossUserVprintp)(OssGlobal *world, const char *format, va_list ap));

Sets or gets the default C library vprintf() function and standard output stream with your own custom va_list printing function and standard output stream.

Arguments

world
Pointer to the OssGlobal variable.
stream
Output stream to which the output is written (such as stdout or a file).
ossUserVprintp
Function pointer for your custom va_list print function.

See Also


int ossInitSync(void);
void ossTermSync(void);

Initializes or releases serialization resources that support cross-thread synchronization. These functions must be called to achieve thread safety in the following situations:

  • when running multi-threaded applications which use the OSS static libraries (for example, toedcomd.lib) on Windows.
  • when running multi-threaded applications on EBCDIC machines (for example, AS/400 and MVS [EBCDIC is an IBM-specific character set]).

ossInitSync() must be called before the first call to ossinit() | ossWinit().

ossTermSync() must be called after the last call to ossinit() | ossWinit().

Return Value

If ossInitSync() is successful, returns zero. Otherwise, returns MUTEX_NOT_CREATED.

Example

OssGlobal w, *world = &w;
  . . . 
if(!ossInitSync(void))
  ossinit(world, bcas);
else
  return;

See Also

ossinit()


int ossIntsToGeneralizedTime(OssGlobal *world, unsigned int year,
           unsigned int month, unsigned int day,
           unsigned int hour, unsigned int minute, unsigned int second,
           unsigned int fraction, unsigned short precision, int local_utc_mindiff,
char *timeString); int ossIntsToUTCTime(OssGlobal *world, unsigned int year,
           unsigned int month, unsigned int day,
           unsigned int hour, unsigned int minute, unsigned int second,
           int utc_mindiff,
           char *timeString);

Converts INTEGER field values of GeneralizedTime or UTCTime types into ASN.1 value string representation.

Arguments

world
Pointer to the OssGlobal variable.
year/month/.../second
Corresponding fields of GeneralizedTime or UTCTime types.
fraction
Fractional part of the seconds field (for example: milliseconds).
precision
Number of digits in the fractional part of the seconds field (number of digits found after the decimal point in the timeString).
local_utc_mindiff
Positive or negative minute differential between local time and GMT, set to 0 for the local time, and to 1 for UTC time.
timeString
String (preallocated) that is populated with the GeneralizedTime or UTCTime types in ASN.1 value notation format.

Return Value

If successful, it returns zero. Otherwise, it returns BAD_TIME error.

Example

UTCTime myTime;
OssGlobal w, *world = &w;
char utc_timeString[40], gen_timeString[40];
int retcode;
myTime.year=12; myTime.month=8; myTime.day = 23; myTime.hour = 12;
myTime.minute = 33; myTime.second=27; myTime.mindiff = -300;
ossIntsToUTCTime(world, myTime.year, myTime.month, myTime.day,
   myTime.hour, myTime.minute, myTime.second, myTime.mindiff,
   utc_timeString);
ossIntsToGeneralizedTime(world, 2001, myTime.month, myTime.day,
   myTime.hour, myTime.minute, myTime.second, 258, 3, 1,
   gen_timeString);
ossPrint(world, "UTC TimeString: %s \n", utc_timeString);
ossPrint(world, "Generalized TimeString: %s \n", gen_timeString);

Prints:

UTC TimeString: 120823123327-0500
Generalized TimeString: 20010823123327.258Z

See Also

ossUTCTimeToInts() | ossGeneralizedTimeToInts()


int ossSetTemporaryBuffer(OssGlobal *world, OssBuf *buf);

Used with TOED to preallocate a large memory buffer which the encoder/decoder can reuse for temporary storage. This is an alternative that leads to a better performance during encoding/decoding specifications rather than calling several internal malloc() | free() operations to handle temporary storage. Note that you must make sure that the preallocated buffer is freed after encode/decode operations are finished.

Arguments

world
Pointer to the OssGlobal variable.
buf
OssBuf type variable whose value field references the preallocated buffer to hold temporary storage (the error message D0132S or E0132S is issued if your buffer is too small), and whose length field is the length (in bytes) of the buffer. To revert to the default temporary allocation/deallocation behavior of the encoder/decoder, set buf to NULL.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value. For non-TOED encoder/decoder, it returns UNIMPLEMENTED.

Example

OssBuf tempBuf;

. . .
  
tempBuf.value = (char *)malloc(100000);
tempBuf.length = 100000;

ossSetTemporaryBuffer(world, &tempBuf);

Remarks

The temporary memory block must exceed 32 bytes and must be 5 to 10 kilobytes larger than the actual memory needed to hold the encoded/decoded data chunk. To learn how much memory a sample encoded message requires, use ossDetermineEncodingLength(). We recommend that you allocate twice as much memory than is required for the largest PDU. The decoder requires more memory than the encoder needs for the same message.

See Also


int ossSetUserStack(OssGlobal *world, OssBuf *stack);

Allows you to preallocate a memory area for encoding/decoding operations. You can use it if you experience a stack overflow error due to a limited stack space in your operating environment. Make sure you free the preallocated stack-space buffer when you finish using it.

The ossSetUserStack() function is available for SOED. The specific components that benefit from the use of this function are: the PER encoder/decoder, ossCpyValue() function, and ossCmpValue() function.

Arguments

world
Pointer to the OssGlobal variable.
stack
OssBuf whose value field references your preallocated memory and whoselength field contains the length in bytes of your preallocated buffer. To revert to the default temporary stack allocation or deallocation behavior of the encoder/decoder, set OssBuf.value argument to NULL.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero error. If SOED is not in use or if your runtime platform does not implement dynamic allocation of large chunks of automatic data, it returns UNIMPLEMENTED.

Example

OssGlobal w, *world = &w;
OssBuf encodedData;
OssBuf stackBuf;
int myPduNum = MyASN1DataType_PDU;
MyASN1DataType *decodedDataPtr;

. . . . 

stackBuf.value = (*world->mallocp)(4096*sizeof(char)););
stackBuf.length = 4096;  /* size of initial buffer */

ossSetUserStack(world, &stackBuf);
ossDecode(world, &myPduNum, &encodedData, (void **)&decodedDataPtr);

. . . .

(*world->freep)(stackBuf.value);
ossterm(world);

Remarks

We recommend that you allocate at least twice as much memory than is required for the largest PDU. Through trial and error, a larger chunk of memory is required, depending upon the complexity of your ASN.1 specification.

See Also

ossSetTemporaryBuffer()


int ossStartPointDurationIntervalToString (OssGlobal *world,
           ossTimePoint *start, ossDuration *dur, char **dest);
int ossStartPointDurationRecIntervalToString(OssGlobal *world,
           ossTimePoint *start, ossDuration *dur, int rec, char **dest);

Constructs the string representation of an ISO 8601 [recurring] time interval in the form of a start-duration pair from its individual components. Use these functions when the TIME type has a Property settings constraint applied, the Basic property is set to [Rec]Interval and Interval-type is set to "SD".

The ossGetTimeKind() function returns the oss_tk_StartPointDuration[Rec]Interval for the newly constructed time value.

Arguments

world
Pointer to the OssGlobal variable.
start
Contains the start point of the time interval.
dur
Contains the duration of the time interval.
rec
Number of recurrences.
dest
Output string representation of the ISO 8601 time interval. If *dest is NULL, the function automatically allocates the output string (to deallocate it, call ossFreeMemory()) or a pointer to the memory that you allocated.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero error (BAD_TIME).

Example

OssGlobal w, *world = &w;
int rc, rec = 0;
ossTimePoint start;
ossDuration dur;
char *result = NULL;
  . . . 
ossStringToStartPointDurationRecInterval(world, 
   "R5/1985-04-12T23:20:50/P1Y4M20DT30M", &start, &dur, &rec);
dur.years += 2;
dur.bit_mask |= OSS_de_hours_present;
dur.hours = 1;
rec -= 2;
ossStartPointDurationRecIntervalToString(world, 
&start,
&dur, rec, &result);
ossPrint(world, "Resulting string: %s\n", result);
ossFreeBuf(world, result);

Prints:

Resulting string: R3/1985-04-12T23:20:50/P3Y4M20DT1H30M

See Also

ossStringToStartPointDurationInterval() | ossStringToStartPointDurationRecInterval()


int ossStartPointEndPointIntervalToString (OssGlobal *world,
           ossTimePoint *start, ossTimePoint *end, char **dest);
int ossStartPointEndPointRecIntervalToString(OssGlobal *world,
           ossTimePoint *start, ossTimePoint *end, int rec, char **dest);

Constructs the string representation of an ISO 8601 [recurring] time interval in the form of a start-end pair from its individual components. Use these functions when the TIME type has a Property settings constraint applied, the Basic property is set to [Rec]Interval and Interval-type is set to "SE".

The ossGetTimeKind() function returns the oss_tk_StartPointEndPoint[Rec]Intervalfor the newly constructed time value.

Arguments

world
Pointer to the OssGlobal variable.
start/end
Contains the start or end point of the time interval.
rec
Number of recurrences.
dest
Output string representation of the ISO 8601 time interval. If *dest is NULL, the function will automatically allocate the output string (you can deallocate it later by calling ossFreeMemory()) or a pointer to the memory that you allocated by yourself.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero error (BAD_TIME).

Example

OssGlobal w, *world = &w;
int rc;
ossTimePoint start, end;
char *result = NULL;
  . . . 
ossStringToStartPointEndPointInterval(world, 
   "1985-04-12T23:20:50/1985-06-25T10:30:00", &start, &end);
end.seconds = 50;
end.years += 4;
ossStartPointEndPointIntervalToString(world, &start, &end, &result);
ossPrint(world, "Resulting string: %s\n", result);
ossFreeBuf(world, result);

Prints

Resulting string: 1985-04-12T23:20:50/1989-06-25T10:30:50

See Also

ossStringToStartPointEndPointInterval() | ossStringToStartPointEndPointRecInterval()


int ossStringToDurationEndPointInterval(OssGlobal *world,
          char *in, ossDuration *dur, ossTimePoint *end);
int ossStringToDurationEndPointRecInterval(OssGlobal *world,
          char *in, ossDuration *dur, ossTimePoint *end, int *rec);

Parses the string representation of an ISO 8601 time interval expressed by a [number of recurrences of] "duration-end" pair and creates the parsed (binary) values of the components of this pair [and recurrence]. Use these functions when the ossGetTimeKind() function returns an oss_tk_DurationEndPoint[Rec]Interval for the input time string value. Thus, the corresponding TIME type has a Property settings constraint applied, the Basic property is set to [Rec]Interval, and Interval-type is set to "DE".

Arguments

world
Pointer to the OssGlobal variable.
in
String representation of the ISO 8601 time interval.
dur
Duration of the time interval.
end
End point of the time interval.
rec
Number of recurrences; -1 indicates that it is absent in the input string value.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero error (BAD_TIME).

Example

See ossDurationEndPointIntervalToString()

See Also

ossDurationEndPointIntervalToString() | ossDurationEndPointRecIntervalToString()


int ossStringToDurationInterval(OssGlobal *world, char *inp, ossDuration *dur);
int ossStringToDurationRecInterval(OssGlobal *world, char *inp, ossDuration *dur, int *rec);

Parses the string representation of an ISO 8601 [recurring] time interval and creates the parsed (binary) duration value. Use these functions when the ossGetTimeKind() function returns the oss_tk_Duration[Rec]Interval for the input time string value. Thus, the corresponding TIME type has a Property settings constraint applied, the Basic property is set to [Rec]Interval and Interval-type is set to "D".

Arguments

world
Pointer to the OssGlobal variable.
inp
String representation of the ISO 8601 time interval.
dur
Holds the duration value.
rec
Number of recurrences; -1 indicates that it is absent in the input string value.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero error (BAD_TIME).

Example

See ossDurationEndPointIntervalToString() | ossDurationIntervalToString().

See Also

ossDurationIntervalToString() | ossDurationRecIntervalToString()


int ossStringToStartPointDurationInterval(OssGlobal *world,
           char *inp, ossTimePoint *start, ossDuration *dur);
int ossStringToStartPointDurationRecInterval(OssGlobal *world,
          char *inp, ossTimePoint *start, ossDuration *dur, int *rec);

Parses the string representation of an ISO 8601 [recurring] time interval expressed by a start-duration pair and creates the parsed (binary) values of the components of this pair. Use these functions when the ossGetTimeKind() function returns theoss_tk_StartPointDuration[Rec]Interval enumeration for the input time string value. Thus, the corresponding TIME type has a Property settings constraint applied, the Basic property is set to [Rec]Interval and Interval-type is set to "SD".

Arguments

world
Pointer to the OssGlobal variable.
inp
String representation of the ISO 8601 time interval.
start
Contains the start point of the time interval.
dur
Holds the duration value.
rec
Number of recurrences; -1 indicates that it is absent in the input string value.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero error (BAD_TIME).

Example

See ossStartPointDurationIntervalToString()

See Also

ossStartPointDurationIntervalToString() | ossStartPointDurationRecIntervalToString()


int ossStringToStartPointEndPointInterval(OssGlobal *world,
           char *inp, ossTimePoint *start, ossTimePoint *end);
int ossStringToStartPointEndPointRecInterval(OssGlobal *world,
           char *inp, ossTimePoint *start, ossTimePoint *end, int *rec);

Parses the string representation of an ISO 8601 [recurring] time interval expressed by a start-end pair and creates the parsed (binary) values of the components of this pair. Use these functions when the ossGetTimeKind() function returns the oss_tk_StartPointEndPoint[Rec]Intervalenumeration for the input time string value. Thus, the corresponding TIME type has a Property settings constraint applied, the Basic property is set to [Rec]Interval and Interval-type is set to "SE".

Arguments

world
Pointer to the OssGlobal variable.
start/end
Is populated with the "start/end point" of the time interval.
rec
Number of recurrences; where -1 will indicate that it is absent in the input string.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero error (BAD_TIME).

Example

See ossStartPointEndPointIntervalToString()

See Also

ossStartPointEndPointIntervalToString() | ossStartPointEndPointRecIntervalToString()


int ossStringToTimePoint(OssGlobal *world, char *inp, ossTimePoint *dest);
int ossTimepointToString(OssGlobal *world, ossTimePoint *inp, char **dest);

Converts an ISO 8601 time point value between its string representation and C-representation. Use it when the TIME type has a Property settings constraint applied and the Basic property is set to Time or Date-Time or Date (ossGetTimeKind() returns oss_tk_TimePoint for such time values).

Arguments

world
Pointer to the OssGlobal variable.
inp/dest
Input/output time point. When char *dest is NULL, the function automatically allocates the output string. To deallocate it, call ossFreeMemory(). Otherwise, point it to the memory that you allocated.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero error (BAD_TIME).

Example

OssGlobal w, *world = &w;
int rc;
ossTimepoint tp;
char *result = NULL; /* Let ossTimePointToString allocate memory */
  . . . 
ossStringToTimePoint (world, "1985-05-10", &tp);
tp.years = 2006; /* Modify years component */
ossTimePointToString(world, &tp, &result);
ossPrint(world, "Resulting string: %s\n", result);
ossFreeBuf(world, result);

Prints:

Resulting string: 2006-05-10 

int ossVprintWin(struct ossGlobal *world, const char *format, va_list ap);

ossVprintWin() is similar to the vprintf() C library function. It is called when the Borland C++ Builder (and OSS DLLs) is used with a regular (Microsoft VC++) copy of the OSS ASN.1 Tools for C, in a custom implementation of ossPrint() for such cases. The custom version of ossPrint() is shipped (only in the Windows version) in the samples directory as ossprint.c.

Return Value

If successful, it returns the number of characters written to the output. Otherwise, it returns -1.

Example

int ossPrint(struct ossGlobal *world, const 
char *fmt, ...)
{
  int err = 0;
  va_list ap;
  va_start(ap, fmt);
  if (world)
     err = ossVprintWin(world, fmt, ap);
  else
     vrintf(fmt, ap);
  va_end(ap);
  return err;
}

See Also

ossPrint()


XML Functions

The functions described in this section are used for converting ASN.1 binary messages to and from XML using one of the ASN.1 XML Encoding Rules: Basic, Canonical, or Extended.

int ossBinary2XML(OssGlobal *world,
       int pdunum, ossEncodingRules sourceRules, OssBuf *binSource, OssBuf *xmlTarget);
int ossXML2Binary(OssGlobal *world,
       int pdunum, ossEncodingRules targetRules, OssBuf *xmlSource, OssBuf *binTarget);

These functions convert ASN.1 binary messages to and from XML using ASN.1 binary encoding rules (BER, CER, DER, PER, CPER, OER, and COER) and XER text encoding rules (Basic XER, Canonical XER and Extended XER). The default XML encoding rules used for conversion are determined by the options specified at ASN.1-compile time (-xer for Basic, -cxer for Canonical, and -exer for Extended XML Encoding Rules). When you specify more than one option, the precedence is: E-XER, XER, CXER.

To set or retrieve the default encoding rules and detailed XER rules, use ossSetXMLEncodingRules() | ossGetXMLEncodingRules().

Arguments

world
Pointer to the OssGlobal variable.
pdunum
PDU number of the data type.
sourceRules | targetRules
Specifies the encoding rules for conversion (OSS_BER, OSS_CER, OSS_DER, OSS_PER_ALIGNED etc.).
binSource | xmlSource
OssBuf structure whose value field references the encoded ASN.1 value (binary or XER-text) and whose length field contains the length (in bytes) of this value.
xmlTarget | binTarget
OssBuf structure whose value field will reference the output value (XER encoding text or binary, accordingly). To automatically allocate output memory, set OssBuf.value to NULL and OssBuf.length to zero. To free the memory, call ossFreeBuf(). Otherwise, preallocate memory and set the value and length accordingly.

Remarks

The ossBinary2XML() and ossXML2Binary() functions perform conversion by decoding and then re-encoding the input message. Starting with version 11.0, the functions check if, at decoding stage, an open type or contents constrained type is left undecoded. This is possible when component relation constraints cannot be resolved for an extensible open type, when the OSS.NoConstrain compiler directive is applied to an open or contents constrained type, or when you use the TOED library without specifying the -autoencdec and -constraints options at ASN.1 compile time. Such an undecoded type cannot be converted. In this case, the functions issue the D0373S error and return the CONVERSION_NOT_POSSIBLE code.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

See Also

ossGetXMLEncodingRules() | ossSetXMLEncodingRules()


int ossDateToInts(OssGlobal *world,
       char *dateTimeString, int *year, unsigned int *month, unsigned int *day, int *local_utc_mindiff);
int ossIntsToDate(OssGlobal *world,
       int year, unsigned int month, unsigned int day, int local_utc_mindiff, char **dateTimeString);

int ossDateTimeToInts(OssGlobal *world,
       char *dateTimeString, int *year, unsigned int *month, unsigned int *day,
       unsigned int *hours, unsigned int *minutes, unsigned int *seconds,
       char **fraction, unsigned int *precision, int *local_utc_mindiff);
int ossIntsToDateTime(OssGlobal *world,
       int year, unsigned int month, unsigned int day,
       unsigned int hours, unsigned int minutes, unsigned int seconds,
       char *fraction, unsigned int precision, int local_utc_mindiff, char **dateTimeString);

int ossDurationToInts(OssGlobal *world,
       char *dateTimeString, ossBoolean *negative,
       unsigned int *years, unsigned int *months, unsigned int *days,
       unsigned int *hours, unsigned int *minutes, unsigned int *seconds,
       char **fraction, unsigned int precision);
int ossIntsToDuration(OssGlobal *world,
       ossBoolean negative, unsigned int years, unsigned int months, unsigned int days,
       unsigned int hours, unsigned int minutes, unsigned int seconds,
       char *fraction, unsigned int precision, char ** dateTimeString);

int ossGDayToInts(OssGlobal *world,
       char *dateTimeString, unsigned int *day, int *local_utc_mindiff);
int ossIntsToGDay(OssGlobal *world,
       unsigned int day, int local_utc_mindiff, char ** dateTimeString);

int ossGMonthDayToInts(OssGlobal *world,
       char *dateTimeString, unsigned int *month, unsigned int *day, int *local_utc_mindiff);
int ossIntsToGMonthDay(OssGlobal *world,
       unsigned int month, unsigned int day, int local_utc_mindiff, char ** dateTimeString);

int ossGMonthToInts(OssGlobal *world,
       char *dateTimeString, unsigned int *month, int *local_utc_mindiff);
int ossIntsToGMonth(OssGlobal *world,
       unsigned int month, int local_utc_mindiff, char **dateTimeString);

int ossGYearToInts(OssGlobal *world, char *dateTimeString, int *year, int *local_utc_mindiff);
int ossIntsToGYear(OssGlobal *world, int year, int local_utc_mindiff, char **dateTimeString);

int ossGYearMonthToInts(OssGlobal *world,
       char *dateTimeString,int *year, unsigned int *month, int *local_utc_mindiff);
int ossIntsToGYearMonth(OssGlobal *world,
       int year, unsigned int month, int local_utc_mindiff, char **dateTimeString);

int ossTimeToInts(OssGlobal *world,
       char *dateTimeString, unsigned int *hours, unsigned int *minutes, unsigned int *seconds,
       char **fraction, unsigned int *precision, int *local_utc_mindiff);
int ossIntsToTime(OssGlobal *world,
       unsigned int hours, unsigned int minutes, unsigned int seconds, char *fraction,
       unsigned int precision, int local_utc_mindiff, char **dateTimeString);

These functions convert XML Schema date and/or time types, including duration, gYear, gMonthDay, etc., to and from string representation and C INTEGERs (representing individual components of date or time).

Arguments

world
Pointer to the OssGlobal variable.
year/month/day/hours/minutes/seconds/local_utc_mindiff
Individual components of XML date and/or time values.
negative
Indicates whether duration is negative (TRUE) or not (FALSE).
fractions, precision
String of decimal digits representing fractions of a second with the precision indicating the number of digits (chars) in the fractions. When parsing the input date/time string, the memory for the output fraction string is not allocated. Instead, it points to the input string fractions location, which allows arbitrary long fraction values.
dateTimeString
XML Schema date and/or time in text form. For functions where it is an output argument, you can either preallocate memory for the string or set the pointer to NULL and allow the library to allocate it (to free it, use ossFreeBuf()).

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value (BAD_TIME).

Example

OssGlobal w;
int year, month, day, hours, minutes, seconds, precision, local_utc_mindiff;
char *fractions = 0;
  . . . 
ossDateToInts (&w, "1985-05-10+05:00", &year, &month, &day, &local_utc_mindiff);
ossPrint(&w, "Year: %d, Month: %d, Day: %d, UTC min diff: %d.\n",

year, month, day, local_utc_mindiff);
  . . . 
char * dateString = NULL;
ossIntsToDate (world, 2003, 11, 15, -120, &dateString);
ossPrint(world, "Date string: %s.\n", dateString);
ossFreeBuf(world, dateString);
  . . .
ossDateTimeToInts (world, "2003-11-15T13:22:05.234-01:30",
&year, &month, &day, &hours, &minutes, &seconds, &fraction,
&precision, &local_utc_mindiff);
ossPrint(world, "Year: %d, Month: %d, Day: %d, Hours: %d, Minutes: %d \n", 
  year, month, day, hours, minutes);
ossPrint(world, "Seconds: %d, Fractions: %.*s, UTC min dif: %d. \n", 
  seconds, precision, fractions, local_utc_mindiff);
  . . .
ossBoolean negative; 
ossDurationToInts (world, "P5Y2M5D10H30M25.65S", 
  &negative, &years, &months, &days, &hours, 
  &minutes, &seconds, &fraction, &precision);
ossPrint(world, "Y: %d, M: %d, D: %d, H: %d, M: %d, "S: %d, F: 
                      %.*s. \n", 
  year, month, day, hours, minutes, seconds, precision, fractions);
  . . .
  ossGMonthDayToInts (world, "--06-22Z", &month, &day, &local_utc_mindiff);
ossPrint(world, "Month: %d, Day: %d", month, day);
if(local_utc_mindiff == OSS_UTC_DIFF_Z){
  ossPrint(world, " Coordinated Universal Time.\n");
} else if(local_utc_mindiff == OSS_UTC_DIFF_ABSENT){
ossPrint(world, " no Time Zone specified.\n");
 } else {
ossPrint(world, ", UTC minutes: %d.\n", local_utc_mindiff);
}

Prints:

Year: 1985, Month: 5, Day: 10, UTC min diff: 300.
Date string: 2003-11-15-02:00.
Year: 2003, Month: 11, Day: 15, Hours: 13, Minutes: 22
Seconds: 5, Fraction: 234, UTC min dif: -90.
YY: 5, M: 2, D: 5, H: 10, M: 30 S: 25, F: 65.
Month: 6, Day: 22 Coordinated Universal Time.

Remarks

The Coordinated Universal Time (UTC) difference is represented in number of minutes. Two special values, OSS_UTC_DIFF_Z and OSS_UTC_DIFF_ABSENT (defined to UINT_MAX and UINT_MAX - 1, respectively) indicate that the zone is UTC (with "Z" and no difference) or indicate that no time zone is specified, respectively. Any other values of local_utc_mindiff, positive or negative, are interpreted as time zone specifications. The absolute value for local_utc_mindiff cannot exceed 840 minutes (14 hours).

The parts in the duration input string are optional, and you can have at least one. The function ossDurationToInts() outputs zero for the fields that are absent in the input durationString.


int ossGetNamespacePrefix(OssGlobal *world, char *ns, char **prefix);
int ossSetNamespacePrefix(OssGlobal *world, char *ns, char *prefix);

Gets or sets a prefix string to associate with a namespace declared (using E-XER encoding instructions) in one of the input ASN.1 specifications. The prefix affects only the encoder and sets the default namespace as the namespace of the root element of the E-XER encoding. For other namespaces used in the E-XER encoding, the encoder uses prefixes declared in the ASN.1 specification.

The encoder assigns prefixes to namespace URIs under the following circumstances:

  • When you do not specify a default namespace (when you do not call ossSetNamespacePrefix() with a NULL prefix) and do not specify a prefix for the root element, the encoder checks whether the default namespace can be used safely. When both conditions are met, the encoder associates the default empty prefix with the root element, and the prefixes declared in the ASN.1 specification (or prefixes specified by calling ossSetNamespacePrefix()) are used for the rest of namespaces. Otherwise, no default namespace is used for the E-XER encoding.
  • When you specify a default namespace (when you call ossSetNamespacePrefix() with a NULL prefix), the encoder associates the default empty prefix with the namespace that you select, and prefixes declared in the ASN.1 specification (or prefixes specified by ossSetNamespacePrefix()) are used for the rest of the namespaces.

Arguments

world
Pointer to the OssGlobal variable.
ns
String containing the namespace URI.
prefix
String containing the prefix for that namespace. You do not need to delete the memory allocated for the ouput string.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

/* set the prefix "ex" to the namespace "http://example.org" */
prefixChanged = ossSetNamespacePrefix (world, "http://example.org", 
"ex"); 
if(prefixChanged == 0)
ossPrint("Prefix 'ex' set for the namespace 'http://example.org"."));

Remarks

If your original schema contains unqualified elements, wildcards, or uses QNames (as defined by the W3C XML Namespaces document), you cannot set the default namespace (you cannot specify a NULL prefix). Otherwise, the function returns DEFAULT_PREFIX_NOT_ALLOWED.

For namespaces used in an E-XER encoding that are not declared in the input schemas (such as the URI component of a QName value), the encoder generates artificially non-empty prefixes that are guaranteed to be unique in the E-XER encoding.


int ossGetXMLEncodingRules(OssGlobal *world);
int ossSetXMLEncodingRules(OssGlobal *world, ossEncodingRules xml_rule);

Gets or sets the XML encoding rules used by ossXML2Binary() and ossBinary2XML() for performing direct conversions from XML to binary and vice versa. The XML encoding rules returned are: Basic XML Encoding Rules (OSS_XER), Canonical Encoding Rules (OSS_CXER), or Extended Encoding Rules (OSS_EXER). The default XML encoding rules used for conversion are determined by the options specified at ASN.1-compile time (-xer for Basic, -cxer for Canonical and -exer for Extended XML Encoding Rules, accordingly). When you specify more than one option, the precedence is: E-XER, XER, CXER.

Arguments

world
Pointer to the OssGlobal variable.
xml_rule
XML encoding rule: OSS_XER, OSS_CXER, OSS_EXER.

Return Value

ossGetXMLEncodingRules() function returns one of the XML encoding rules: OSS_EXER, OSS_XER, OSS_CXER. If none of them is accessible, the function returns -1.

If successful, ossSetXMLEncodingRules() returns a value of zero. Otherwise, it returns a non-zero value (BAD_ENCRULES).

See Also

ossBinary2XML() | ossXML2Binary()


int ossIdentifyPDUByEXERName(OssGlobal *world, unsigned char *uri, unsigned char *name, int *pdu);

Finds the compiler-generated PDU identifier associated with an XML element name. The name is interpreted as the root E-XER element name. The matching PDU (if any) is identified and its number is returned by the function. If there are several PDU types with the same root element name in the input syntax, the function returns DATA_ERROR.

Arguments

world
Pointer to the OssGlobal variable.
uri
Namespace URI if the name is qualified (otherwise it is NULL).
name
Element local name that cannot be NULL.
pdu
Pointer to a PDU value.

Return Value

If successful, it returns zero. Otherwise, it returns an error code.


void ossPrintXML(OssGlobal *world, char *encodedData, long length, ossBoolean pretty_print);

Prints well-formatted XER encodings. We recommend that you use this function when printing an XER encoding.

Arguments

world
Pointer to the OssGlobal variable.
encodedData
XER encoding (OssBuf.value field of the structure referencing the encoding).
length
Length (in bytes) of the XER encoding (the OssBuf.length field of the encoding).
pretty_print
ossBoolean variable used to specify whether the input XER encoding is to be formatted.

Example

OssGlobal w, *world = &w;
MyASN1PDU *inputData;
OssBuf encodedData;
  . . . 
ossEncode(world, myPduNum, inputData, &encodedData);

ossPrintXML(world, encodedData.value, encodedData.length, TRUE);

See Also

ossPrintXPER()


int ossSetXmlDTD(OssGlobal *world, char *pduName, char *externalID, short dtdKind);

Specifies the general data schema (DTD - Data Type Definition) that corresponds to an XER encoding. You can use it to view and edit the output produced by ossEncode() in a non-ASN.1-specific XML tool. pduName and externalID must be global strings that remain accessible for all subsequent calls of ossEncode()(the library does not save a copy of these strings).

Arguments

world
Pointer to the OssGlobal variable.
pduName
Name of the PDU in the next XER encoding to which a DTD file is associated.
externalID
Path name or reference to the DTD file.
dtdKind
OSS_XDTD_SYSTEM (for system DTD files), OSS_XDTD_PUBLIC (for public DTD files), or OSS_XDTD_NONE (to disable the DTD file reference, in which case other DTD-related arguments do not apply).

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

ossSetXmlDTD(world, "Record", "dtd/Record.dtd", OSS_XDTD_SYSTEM);

The following line is added in the subsequent XER encodings:

<!DOCTYPE Record SYSTEM "dtd/Record.dtd">

int ossSetXmlStylesheet(OssGlobal *world, char *xslFilePath);

Provides control over the browser format of the XML output produced by the ossEncode() function. It instructs the encoder to include a reference to an XSL stylesheet in the XER encoding. xslFilePath must point to a global string that remains accessible for all subsequent calls of the ossEncode()(the library does not save a copy of this string).

Arguments

world
Pointer to the OssGlobal variable.
xslFilePath
Path to the XSL stylesheet to be referenced by the subsequent PDU encodings, or NULL to disable such reference.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

ssSetXmlStylesheet(world, "xsl/customized-Record.xsl");

The encoder places the following line in the output XER encoding:

<?xml:stylesheet type="text/xsl" href="xsl/customized-Record.xsl"?>

Zlib Compression Functions

This section describes functions used to compress ASN.1 encodings employing either an algorithm implemented by the standard zlib or a custom compression algorithm. For more details and examples, see Zlib Compression.

int ossCompress(OssGlobal *world, OssBuf *input, OssBuf *output, long prefix_len);
int ossUnCompress(OssGlobal *world, OssBuf *input, OssBuf *output, ossBoolean prefix);

Compress or uncompress the encoding data via built-in zlib compressor. These functions cannot be used if you specify an alternative data transformation routine with the ossSetCompressDecompressFunctions() function.

Arguments

world
Pointer to the OssGlobal variable.
input
Input data (either compressed or uncompressed, depending on the function).
output
Output data (either compressed or uncompressed, depending on the function). To allocate memory automatically, set the value or length field of the structure to NULL.
prefix_len
Length of an input data prefix that should be copied to the output without change. It is not used in the ASN.1/C runtime and must be set to zero.
prefix
Indicates whether or not input is prefixed by data that should be copied to the output without decompression. It is not used in the ASN.1/C runtime and must be set to FALSE.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

OssGlobal  *world;
OssBuf     encodedData;       /* length and address of encoded data */
/* length and address of encoded compressed data */
OssBuf     compressedData;
/* length and address of encoded decompressed data */
OssBuf     decompressedData;
DataPacket myPacket;          /* unencoded data */
DataPacket *decodedPacketPtr; /* address of decoded data */
int        pdu_num = DataPacket_PDU;

. . . .

encodedData.value = NULL;  /* Intialize encoder output buffer */
encodedData.length = 0;

/* Encode the data.  Return non-zero for failure.              */
if (ossEncode(world, DataPacket_PDU, &myPacket, &encodedData)) {
    ossPrint(world, "%s\n", ossGetErrMsg(world));  /* an error occurred,
                                                    * print errmsg */
    ossterm(world);  /* Free up allocated resources */
    return 1;
}

compressedData.value = NULL;  /* Intialize output buffer */
compressedData.length = 0;

/* Compress the data. Return non-zero for failure.             */
if (ossCompress(world, &encodedData, &compressedData, 0)) {
    ossPrint(world, "%s\n", ossGetErrMsg(world));  /* an error occurred,
                                                    * print errmsg */
    ossFreeBuf(world, encodedData.value); /* Free up encoder output buffer */
    ossterm(world);  /* Free up allocated resources */
    return 1;
}
ossFreeBuf(world, encodedData.value); /* Free up encoder output buffer */

decompressedData.value = NULL; /* Intialize output buffer */
	decompressedData.length = 0;

/* Decompress the data. Return non-zero for failure.           */
if (ossUnCompress(world, &compressedData, &decompressedData, FALSE)) {
    ossPrint(world, "%s\n", ossGetErrMsg(world));  /* an error occurred,
                                                    * print errmsg */

    /* Free up compression output buffer */
    ossFreeBuf(world, compressedData.value);
    ossterm(world);  /* Free up allocated resources */
    return 1;
}

ossFreeBuf(world, compressedData.value); /* Free up compression output buffer */
decodedPacketPtr = NULL;

/* Decode the data.  Return non-zero for failure.              */
if (ossDecode(world, &pdu_num, &decompressedData,
                        (void **)&decodedPacketPtr)) {
    ossPrint(world, "%s\n", ossGetErrMsg(world));  /* an error occurred,
                                                    * print errmsg */
    /* Free up decompression output buffer */
    ossFreeBuf(world, decompressedData.value);
    ossterm(world);  /* Free up allocated resources */
    return 1;
} else { /* Print out the data that was just decoded. */
    /* Free up decompression output buffer */
    ossFreeBuf(world, decompressedData.value);
    ossPrint(world, "\nData decoded to:\n\n"); /* successfully decoded */
    ossPrintPDU(world, pdu_num, decodedPacketPtr);
    ossFreePDU(world, pdu_num, decodedPacketPtr); /* free up PDU */
    ossterm(world);  /* Free up allocated resources */
    return 0;
}

Remarks

This feature is supported only for the default memory manager.


int ossGetCompressDecompressFunctions(OssGlobal *world,
      ossCompFcnPtr *ossCompressFp, ossCompFcnPtr *ossUnCompressFp);
int ossSetCompressDecompressFunctions(OssGlobal *world,
      ossCompFcnPtr ossCompressFp, ossCompFcnPtr ossUnCompressFp);

Sets or gets the user-defined compression and decompression (and/or encryption) functions to be used by the encoder or decoder after the USE_COMPRESSION flag was set. By default, the built-in zlib-based compression or decompression routines are used. If you set the function pointer to NULL, compression or decompression is disabled.

Arguments

world
Pointer to the OssGlobal variable.
ossCompressFp/ossUnCompressFp
Pointer of compression or decompression function. Must have the following prototype:

typedef int (DLL_ENTRY_FPTR *_System ossCompFcnPtr)(OssGlobal *world, unsigned char *outbuf,
     unsigned long *outlen, unsigned char *inbuf, unsigned long inlen, void *info);
inbuf/outbuf and inlen/outlen represent the input/output encoding and length (in bytes) (outlen on entry holds the size in bytes of the encoder/decoder library-allocated output buffer; on exit, set to the size in bytes of the data actually written to the output buffer).
info contains arbitrary data for a particular compression or encryption routine.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.


int ossSetCompressDecompressInfo(OssGlobal *world, void *info);
int ossGetCompressDecompressInfo(OssGlobal *world, void **info);

Sets or gets auxiliary information for the current set of compression and decompression (and/or encryption) functions. For the default zlib you can set the compression level.

Arguments

world
Pointer to the OssGlobal variable.
info
Arbitrary information to be used by the compressor or decompressor (for zlib it is an INTEGER indicating the compression level). To indicate defaults, set it to NULL.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

int compression_level = 9; /* 
Z_BEST_COMPRESSION */
  . . .
ossSetCompressDecompressInfo(world, (void *)&compression_level);

After the call, you can change the value of the compression_level variable without calling the API function, since the passed address references the variable and automatically customizes the compression settings.


int ossGetCompSizeEstimator(ossGlobal *world, ossCompEstFcnPtr *ossCompEstFp);
int ossSetCompSizeEstimator(OssGlobal *world, ossCompEstFcnPtr ossCompEstFp);

Sets or gets the compression size estimating function when using custom compression or encryption routines.

This function estimates the maximum size of compressed data for a given uncompressed PDU. It is useful when allocating memory buffer for the compressed encoding.

By default, the zlib estimation formula is used: the maximum size of the compressed encoding will not exceed the size of the uncompressed data + 0.1% of the uncompressed data size + 12 bytes, regardless of the encoding. However, when using your custom compression/encryption function, this formula might not be applicable and you must provide another maximum size estimating function.

Arguments

world
Pointer to the OssGlobal variable.
ossCompEstFp
Pointer to the compression size estimating function or NULL, if it is the default one. The function prototype is:

typedef unsigned long (DLL_ENTRY_FPTR *_System ossCompEstFcnPtr)
(unsigned char *inbuf, unsigned long inlen, void *info)
inbuf/inlen is the input uncompressed encoding buffer and length in bytes.
info points to an arbitrary data to be used by compression/encryption routine. Your custom size estimator function may not need to refer to the inbuf and info parameters depending on the nature of your compression or encryption algorithm.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.

Example

unsigned long DLL_ENTRY_FDEF zlibEstimator(
unsigned char *inbuf, unsigned long inlen, void *info)
{
return (unsigned long)(inlen * 1.001 + 12);
}
  . . .
ossSetCompSizeEstimator(world, zlibEstimator);

int ossSkipCompressionPrefix (OssGlobal *world, OssBuf *input, long *orig_len, long *compress_len);

Returns the length of the original (uncompressed) and the compressed encoding and modifies the input structure so that the prefix is ignored (an encoding consists of a compression prefix followed by the compressed encoding).

Arguments

world
Pointer to the OssGlobal variable.
input
Compressed encoding (including the compression prefix).
orig_len
Length of the original (uncompressed) encoding.
compress_len
Length of the compressed encoding.

Return Value

If successful, it returns zero. Otherwise, it returns a non-zero value.


This documentation applies to the OSS® ASN.1 Tools for C release 11.3 and later.

Copyright © 2024 OSS Nokalva, Inc. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise, without the prior permission of OSS Nokalva, Inc.
Every distributed copy of the OSS® ASN.1 Tools for C is associated with a specific license and related unique license number. That license determines, among other things, what functions of the OSS ASN.1 Tools for C are available to you.