ASN.1/C Runtime Functions Reference
Contents
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
- ossEncode()
- ossFreePDU()
- ossGetDecodingLength() | ossSetDecodingLength()
- ossGetDecodingFlags() | ossSetDecodingFlags()
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
- ossFreeBuf()
- ossGetEncodingRules() | ossSetEncodingRules()
- ossGetDecodingFlags() | ossSetDecodingFlags()
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
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
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
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 ossGetCsvFlags(OssGlobal *world);
int ossSetCsvFlags(OssGlobal *world, unsigned long flags);
The ossGetCsvFlags() function returns the TOED CSV encoder-specific flags set by the ossSetCsvFlags() function.
The ossSetCsvFlags() function controls the behavior of the TOED CSV encoder.
Arguments
- world
- Pointer to the OssGlobal variable.
- flags
- One or more of the following literals separated by vertical bars ('|'):
- CSV_ENCODE_FORMAT_COLUMN
- CSV_ENCODE_HEADER_ABSENT
- CSV_ENCODE_HEADER_SINGLE
- CSV_ENCODE_HEADER_EXTENDED
- CSV_ENCODE_SKIP_EMPTY
- CSV_ENCODE_BOOLEAN_NUM
- CSV_ENCODE_ENUMERATED_NUM
- CSV_USE_UNICODE_ESCAPE_SEQUENCE
Here is a detailed description of the flags:
| Flag | Description |
|---|---|
CSV_ENCODE_FORMAT_COLUMN |
Instructs the CSV encoder to use the output CSV column format where each value is placed on a separate line, possibly following an optional CSV header name and a column separator. |
CSV_ENCODE_HEADER_ABSENT |
Instructs the CSV encoder to not include a CSV header in the output. |
CSV_ENCODE_HEADER_SINGLE |
Instructs the encoder to include single field names for the innermost simple types in the CSV header. |
CSV_ENCODE_HEADER_EXTENDED |
Instructs the encoder to create the full CSV header where each name starts with a PDU name prefix, a star ("*") is used for unnamed components of SET OF and SEQUENCE OF types, and all intermediate identifiers are joined by a header separator. |
CSV_ENCODE_SKIP_EMPTY |
Instructs the CSV encoder to skip empty CSVs in the output. |
CSV_ENCODE_BOOLEAN_NUM |
Instructs the encoder to encode BOOLEAN type values as numbers ("0" and "1") instead of values ("false" and "true"). |
CSV_ENCODE_ENUMERATED_NUM |
Instructs the encoder to encode ENUMERATED type values as numbers of the corresponding enumerators instead of their identifiers. |
CSV_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. |
After a successful return, the specified flags are set to modify the behavior of the encoder starting with its next call.
Return Value
The ossGetCsvFlags() 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 ossSetCsvFlags() function, a value of zero is returned.
The ossSetCsvFlags() 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 CSV flags is set.
Example
In the following example, the ossGetCsvFlags() function is used:
OssGlobal w, *world = &w; unsigned long flags; .... flags = ossGetCsvFlags(world); if (flags & CSV_ENCODE_FORMAT_COLUMN) ossPrint(world, "Encoding using the CSV column format...\n"); else ossPrint(world, "Encoding using the default CSV row format...\n");
In the following example, the ossSetCsvFlags() function is used:
OssGlobal w, *world = &w; OssBuf encodedData; int myPduNum = MyASN1DataType_PDU; MyASN1DataType myData; ....
For the following syntax:
MyASN1DataType ::= SEQUENCE {
name VisibleString,
age INTEGER,
present BOOLEAN,
handedness ENUMERATED {left-handed(0), right-handed(1), ambidextrous(2)}
}
myData MyASN1DataType ::= {
name "Casey",
age 20,
present TRUE,
handedness right-handed
}
the following CSV is created:
name,age,present,handedness "Casey",20,true,right-handed
To encode in CSV column format using the equal sign ("=") as separator and to print BOOLEAN and ENUMERATED type values as their corresponding numeric values, include the following calls:
ossSetCsvFlags(world, CSV_ENCODE_FORMAT_COLUMN | CSV_ENCODE_BOOLEAN_NUM | CSV_ENCODE_ENUMERATED_NUM); ossSetCsvColumnSeparator(world, '=');
The output encoding is:
name="Casey" age=20 present=1 handedness=1
See Also
- ossGetCsvColumnSeparator() | ossSetCsvColumnSeparator()
- ossGetCsvHeaderSeparator() | ossSetCsvHeaderSeparator()
- ossGetCsvSetOfSeqOfLimit() | ossSetCsvSetOfSeqOfLimit()
- ossGetAllCsvLimit() | ossSetAllCsvLimit()
- -csv
- Comma-Separated Value Encoding Rules
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:
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:
|
STRICT_CONSTRAINT_CHECKING (E/O) |
Enables the following:
|
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:
|
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
- ossEncode()
- ossDecode()
- ossCmpValue()
- ossCpyValue()
- ossCheckConstraints()
- ossDetermineEncodingLength()
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 the following compiler options when ASN.1-compiling your schema: -cer, -der, -per, -uper, -cper, -cuper, -xer, -cxer, -exer, -oer, -coer, -json, -avn, or -csv. The -csv option applies only to the encoder. To switch between multiple encoding rules at runtime, specify multiple compiler options at ASN.1-compile time.
Starting with version 12.0, the Comma-Separated Value (CSV) Encoding Rules are supported only for the encoder. To use these rules with the ossEncode() function, compile with the -csv option specified and set the OSS_CSV flag using the ossSetEncodingRules() function before calling the encoder.
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, OSS_ASN1_VALUE_NOTATION, or OSS_CSV. OSS_CSV applies only to the encoder. The literal 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
- ossEncode()
- ossDecode()
- ossPrintPER()
- ossCompress() | ossUnCompress()
- ossConvertData()
- ossPrintXPER()
- ossXML2Binary()
- ossDetermineEncodingLength()
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
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
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
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
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
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
- ossCleanMemoryHandle()
- ossGetActiveMemoryHandle() | ossSetActiveMemoryHandle()
- ossGetMemoryHandleStat()
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
- ossCreateMemoryHandle() | ossDeleteMemoryHandle()
- ossGetActiveMemoryHandle() | ossSetActiveMemoryHandle()
- ossGetMemoryHandleStat()
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
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
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
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
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
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
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
- ossCleanMemoryHandle()
- ossCreateMemoryHandle() | ossDeleteMemoryHandle()
- ossGetActiveMemoryHandle() | ossSetActiveMemoryHandle()
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
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
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
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 = > 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
- ossCalTimeToGenTimeStruct() | ossCalTimeToUTCTimeStruct()
- ossGenTimeStringToCalTime() | ossUTCTimeStringToCalTime()
- ossGenTimeStructToCalTime() | ossUTCTimeStructToCalTime()
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
- ossCalTimeToGenTimeString() | ossCalTimeToUTCTimeString()
- ossGenTimeStringToCalTime() | ossUTCTimeStringToCalTime()
- ossGenTimeStructToCalTime() | ossUTCTimeStructToCalTime()
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
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
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
- ossAsnValToEncodedRelOid()
- ossEncodedRelOidToAsnVal()
- ossEncodedRelOidToDotVal()
- ossAsnValToEncodedOid()
- ossEncodedOidToAsnVal()
- ossEncodedOidToDotVal()
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
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
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
- ossCalTimeToGenTimeString() | ossCalTimeToUTCTimeString(
- ossCalTimeToGenTimeStruct() | ossCalTimeToUTCTimeStruct()
- ossGenTimeStructToCalTime() | ossUTCTimeStructToCalTime()
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
- ossCalTimeToGenTimeString() | ossCalTimeToUTCTimeString()
- ossGenTimeStructToCalTime() | ossUTCTimeStructToCalTime()
- ossGenTimeStringToCalTime() | ossUTCTimeStringToCalTime()
unsigned int ossGetAllCsvLimit(OssGlobal *world);
int ossSetAllCsvLimit(OssGlobal *world, unsigned int limit);
The ossGetAllCsvLimit() function returns the limit used by the encoder on the number of all CSVs to be created for a top-level PDU type value that may include multiple components for multiple SET OF and SEQUENCE OF type values.
The ossSetAllCsvLimit() function sets the maximum number of all CSVs to create for a top-level PDU type value that may include multiple components for multiple SET OF and SEQUENCE OF type values for which additional CSVs are created.
Arguments
- world
- Pointer to the OssGlobal variable.
- limit
- Maximum number of all CSV records to create for a top-level PDU type value that may include multiple components for multiple SET OF and SEQUENCE OF type values for which additional CSVs are created. This limit is calculated based on the number of components in a SET OF or SEQUENCE OF value in the order of their appearance within the PDU value. For example, all components from the first SET OF or SEQUENCE OF value are included in the encoding, as long as their number does not exceed the maximum number of all components. The number of components from the next SET OF or SEQUENCE OF value is then limited to the maximum number reduced by the number of components from the first SET OF or SEQUENCE OF value, and so on. Once the total number exceeds the maximum limit, only the first component is encoded for the remaining SET OF and SEQUENCE OF values.
Return Value
The ossGetAllCsvLimit() function returns an unsigned integer. Upon a successful call, the limit set for the encoder is returned. If world is NULL, a value of (unsigned long) -1 is returned. If no prior call was made to the ossSetAllCsvLimit() function, a value of 50 is returned.
The ossSetAllCsvLimit() function returns an integer. Upon a successful call, a value of zero is returned; otherwise, a non-zero value is returned.
Example
Mod DEFINITIONS AUTOMATIC TAGS ::= BEGIN
Type ::= SEQUENCE {
sofbool SEQUENCE OF BOOLEAN,
sofint SEQUENCE OF INTEGER
}
value Type ::= {
sofbool {TRUE, FALSE, TRUE},
sofint {1, 2, 3}
}
END
The output CSV without a call to ossSetAllCsvLimit() is:
sofbool,sofint
true,1
true,2
true,3
false,1
false,2
false,3
true,1
true,2
true,3
The output CSV with ossSetAllCsvLimit(world, 5) is:
sofbool,sofint
true,1
true,2
false,1
false,2
true,1
See Also
- ossGetCsvColumnSeparator() | ossSetCsvColumnSeparator()
- ossGetCsvHeaderSeparator() | ossSetCsvHeaderSeparator()
- ossGetCsvSetOfSeqOfLimit() | ossSetCsvSetOfSeqOfLimit()
- ossGetCsvFlags() | ossSetCsvFlags()
- -csv
- Comma-Separated Value Encoding Rules
char ossGetCsvColumnSeparator(OssGlobal *world);
int ossSetCsvColumnSeparator(OssGlobal *world, char separator);
The ossGetCsvColumnSeparator() function returns the column separator used by the CSV encoder. By default, the comma (",") is used as a column separator.
The ossSetCsvColumnSeparator() function sets the CSV column separator used by the CSV encoder.
Arguments
- world
- Pointer to the OssGlobal variable.
- separator
- One of the following values: "," (comma), ";" (semicolon), ":" (colon), or "=" (equal sign).
Return Value
The ossGetCsvColumnSeparator() function returns a single character value that represents the column separator used by the encoder. If world is NULL or no prior call was made to the ossSetCsvColumnSeparator() function, a ',' (comma) character value is returned.
The ossSetCsvColumnSeparator() function returns an integer. Upon a successful call, a value of zero is returned; otherwise, a non-zero value is returned.
Example
OssGlobal w, *world = &w; char colSep;
colSep = ossGetCsvColumnSeparator(world);
if (colSep != ';')
ossSetCsvColumnSeparator(world, ';');
See Also
- ossGetAllCsvLimit() | ossSetAllCsvLimit()
- ossGetCsvHeaderSeparator() | ossSetCsvHeaderSeparator()
- ossGetCsvSetOfSeqOfLimit() | ossSetCsvSetOfSeqOfLimit()
- ossGetCsvFlags() | ossSetCsvFlags()
- -csv
- Comma-Separated Value Encoding Rules
char ossGetCsvHeaderSeparator(OssGlobal *world);
int ossSetCsvHeaderSeparator(OssGlobal *world, char separator);
The ossGetCsvHeaderSeparator() function returns the CSV header separator used by the CSV encoder to create partial or absolute reference ASN.1 names that match the values in the columns. By default, the encoder uses the underscore ("_") as a header separator.
The ossSetCsvHeaderSeparator() function sets the CSV header separator used by the CSV encoder.
Arguments
- world
- Pointer to the OssGlobal variable.
- separator
- One of the following values: "_" (underscore), dash ("-"), period ("."), slash ("/"), or backslash ("\").
Return Value
The ossGetCsvColumnSeparator() function returns a single character value that represents the header separator used by the encoder. If world is NULL or no prior call was made to the ossSetCsvHeaderSeparator() function, an "_" (underscore) character value is returned.
The ossSetCsvColumnSeparator() function returns an integer. Upon a successful call, a value of zero is returned; otherwise, a non-zero value is returned.
Example
OssGlobal w, *world = &w; char hdrSep; hdrSep = ossGetCsvHeaderSeparator(world); if (hdrSep != '.') ossSetCsvHeaderSeparator(world, '.');
See Also
- ossGetAllCsvLimit() | ossSetAllCsvLimit()
- ossGetCsvColumnSeparator() | ossSetCsvColumnSeparator()
- ossGetCsvSetOfSeqOfLimit() | ossSetCsvSetOfSeqOfLimit()
- ossGetCsvFlags() | ossSetCsvFlags()
- -csv
- Comma-Separated Value Encoding Rules
unsigned int ossGetCsvSetOfSeqOfLimit(OssGlobal *world);
int ossSetCsvSetOfSeqOfLimit(OssGlobal *world, unsigned int limit);
The ossGetCsvSetOfSeqOfLimit() function returns the limit used by the encoder on the number of components for each SET OF or SEQUENCE OF value, for which an additional CSV is created.
The ossSetCsvSetOfSeqOfLimit() function sets the maximum number of components for each SET OF or SEQUENCE OF value used by the CSV encoder.
Arguments
- world
- Pointer to the OssGlobal variable.
- limit
- Maximum number of components for each SET OF or SEQUENCE OF value for which an additional CSV should be created.
Return Value
The ossGetCsvSetOfSeqOfLimit() function returns an unsigned integer. Upon a successful call, the limit set for the encoder is returned. If world is NULL, a value of (unsigned long) -1 is returned. If no prior call was made to the ossSetCsvSetOfSeqOfLimit() function, a value of 50 is returned.
The ossSetCsvSetOfSeqOfLimit() function returns an integer. Upon a successful call, a value of zero is returned; otherwise, a non-zero value is returned.
Example
Mod DEFINITIONS AUTOMATIC TAGS ::= BEGIN
Type ::= SEQUENCE {
sofbool SEQUENCE OF BOOLEAN,
sofint SEQUENCE OF INTEGER
}
value Type ::= {
sofbool {TRUE, FALSE, TRUE},
sofint {1, 2, 3}
}
END
The output CSV without a call to ossSetCsvSetOfSeqOfLimit() is:
sofbool,sofint
true,1
true,2
true,3
false,1
false,2
false,3
true,1
true,2
true,3
The output CSV with ossSetCsvSetOfSeqOfLimit(world, 1) is:
sofbool,sofint
true,1
The output CSV with ossSetCsvSetOfSeqOfLimit(world, 2) is:
sofbool,sofint
true,1
true,2
false,1
false,2
See Also
- ossGetAllCsvLimit() | ossSetAllCsvLimit()
- ossGetCsvColumnSeparator() | ossSetCsvColumnSeparator()
- ossGetCsvHeaderSeparator() | ossSetCsvHeaderSeparator()
- ossGetCsvFlags() | ossSetCsvFlags()
- -csv
- Comma-Separated Value Encoding Rules
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 Also
- ossAsnValToEncodedOid() | ossAsnValToEncodedRelOid()
- ossDotValToEncodedOid() | ossDotValToEncodedRelOid()
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:
|
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:
|
OSS_V90_ARRAY_AND_VARYING_SIZE |
Available for the SOED runtime. Prior to version 10.0, memory for the decoded values of:
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
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
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_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
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
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
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
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
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
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 12.0 and later.
Copyright © 2025 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.

