OssControl is an abstract base class from which the ASN.1 compiler derives a class for use with the specification being compiled. Since the class is abstract, objects can only be instantiated in derived forms. The derived class is used for
Some class constructors and methods are for internal use only and are not included in this documentation. Do not use these or any other undocumented methods.
NOTE: In multithreaded programs, do not use one OssControl object for several threads concurrently.
class OssControl { public: int setEncodingRules(OssEncodingRules rules); OssEncodingRules getEncodingRules() const; int setEncodingFlags(unsigned long flags); unsigned long getEncodingFlags() const; int setDecodingFlags(unsigned long flags); unsigned long getDecodingFlags() const; const char *getErrorMsg() const; int printHex(const char *buffer, unsigned long length); int setOutputFile(const char *filename); int resetOutputFile(); virtual int userPrint(FILE *stream, const char *fmt, va_list ap); void print(const char *text); int setXmlStylesheet(const char *xslFilePath); int setXmlDTD(const char *pduName, const char *externalID, short dtdKind); void printXML(const char *buffer, unsigned long length, int pretty_print); int getNamespacePrefix(const char *ns, const char **prefix); int setNamespacePrefix(const char *ns, const char *prefix); int setXMLEncodingRules(OssEncodingRules rules); OssEncodingRules getXMLEncodingRules() const; int setDebugFlags(unsigned long flags); unsigned long getDebugFlags() const; unsigned long getCompatibilityFlags(); int setCompatibilityFlags(unsigned long flag); void setTimeout(long timeout); void setDebugStringTruncate(size_t length); size_t getDebugStringTruncate() const; int valid(); void printJSON(const char *buffer, unsigned long length, int pretty_print); int setJsonFlags(unsigned long flags); unsigned long getJsonFlags() const; int setJsonIndentSize(int indent_size); int getJsonIndentSize() const; void setCompressor(OssCompressor *comp); OssCompressor* getCompressor(); };
Flag | Description |
---|---|
AUTOMATIC_ENCDEC | Specifies automatic encoding of containing structures within open types. This flag eliminates repeated calls to the encoder/decoder when processing structures with nested open types. By default, the encoder/decoder does not handle open types automatically. |
BACK_ALIGN | Tells the encoder to right-justify data within the preallocated output buffer. |
COMPACT_XER_ENCODING | Can be set when the XML encoding rules are selected. The resulting XER encoding contains no whitespace or newline symbols, so its length is shorter. By default, the XER encoder formats the XML output to make it more human-readable. |
DEBUGPDU | Prints trace data as each PDU is encoded, to use for debugging or diagnostic purposes. Only the SOED supports this flag. |
DEFAULT_ALIGN | Instructs the encoder to use the most efficient alignment in the preallocated output buffer. The data will be
|
DEFINITE | Instructs the encoder to use the definite length form when encoding. This flag only applies to BER. |
EXER_ENCODING_OF_DEFAULT_VALUES_AS_COMMENTS | Instructs the E-XER encoder to encode absent DEFAULT fields as XML comments that contain the corresponding default values. |
FRONT_ALIGN | Instructs the encoder to left-justify data within the preallocated output buffer. This flag is required when sequentially encoding several PDUs into one preallocated buffer. |
INDEFINITE | Instructs the encoder to use the indefinite length form when encoding. This flag only applies to BER and can be used only with the SOED. It is ignored by the Lean and the Time-Optimized Encoder/Decoders. |
NOCONSTRAIN | Instructs the encoder to not perform strict constraint checking at runtime for better overall performance. We recommend that you do not use this flag during development as strict constraint checking can help you find errors in your code. |
NOTRAPPING | Disables signal trapping and is the default. See also OSS_TRAPPING. |
OSS_TRAPPING | Enables signal trapping. With signal trapping on, performance suffers somewhat. More importantly, signal trapping is not always thread-safe, depending on the operating system in use. We recommend that you do not enable trapping for multi-threaded applications. In other cases, you can specify this flag to help find coding errors since, with signal trapping enabled, the OSS runtime will return an error code and message, rather than just crashing. The old NOTRAPPING flag is supported for the sake of compatibility, but OSS_TRAPPING takes precedence. That is, if both NOTRAPPING and OSS_TRAPPING are specified then trapping is enabled; if neither flag is specified then trapping is disabled. NOTE: Before release 4.1, the OSS runtime trapped signals by default. |
NO_XML_DECLARATION | Can be specified when the XML encoding rules are selected. This flag prevents the encoder from generating an XML header declaration (for example, <?xml version="1.0" encoding="UTF-8"?>) at the beginning of the resulting XER encoding. By default, such declarations are generated. |
OSS_AUTO_ENCODE_WITHOUT _CHECKING_CONSTRAINT |
Instructs the encoder to disable the extra error check for type values constrained by a component relation constraint. By default, the encoder returns an error if a value is missing from the information object set referred to by the constraint, even if the object set is extensible. |
RELAY_OPEN_TYPES_IN_HEX | Instructs the XER encoder to encode open type values into their hexadecimal equivalents if they cannot be represented as valid XML. 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. When this flag is not set, the encoder does not validate the contents of pre-encoded open types and always puts them in the resulting encoding as is, assuming it is XML. When this flag is set, the encoder checks for well-formed contents and puts them into binary XML. Contents that are not well-formed are put in hexadecimal form. Using this flag slows the encoding process. The hexadecimal content cannot be used
|
STRICT_CONSTRAINT_CHECKING |
|
STRICT_ENCODING_DECODING_RULES | Enables strict checking of conformance to the encoding rules. Starting with version 6.6, the flag enables the following additional checks for the PER encoder:
|
STRICT_PER_ENCODING_OF _DEFAULT_VALUES |
Instructs the Basic-PER encoder not to encode components defined with the DEFAULT value when its value is the default. NOTE: To enable support for this runtime flag in the TOED, compile the TOED generated code file with the OSS_STRICT_PER_ENCODING_OF_DEFAULT_VALUES macro. |
Flag | Description |
---|---|
AUTOMATIC_ENCDEC | Specifies automatic decoding of open types with their containing structures. This flag eliminates repeated calls to the encoder/decoder when processing structures with nested open types. Automatic decoding of open types is possible only when the ASN.1 specification contains enough information for the decoder to determine the type contained in the open type, for example, using the component relation constraints that define the component. If there is not enough information, the open type is left in the encoded form by the decoder. By default, the encoder/decoder does not handle open types automatically. |
DEBUG_ERRORS | Prints a diagnostic message when an error is encountered, before attempting to continue with the current decode operation. |
DEBUGPDU | Prints trace data as each PDU is decoded, to use for debugging or diagnostic purposes. Also, when an error is encountered during a decode operation, a diagnostic message is printed and an attempt is made to continue decoding. That is, when the DEBUGPDU flag is set, DEBUG_ERRORS is implied. |
DONT_DO_ENCODED | Instructs the decoder not to copy/compare encoded open type values. This flag affects only the ASN1Handle::copy and ASN1Handle::equals methods. It does not affect the behavior of the decoder or the OssOpen class. |
DONT_DO_DECODED | Instructs the decoder not to copy/compare decoded open type values. This flag affects only the ASN1Handle::copy and ASN1Handle::equals methods. It does not affect the behavior of the decoder or the OssOpen class. |
DONT_FREE_ENCODED | Instructs the decoder to keep (not free) the encoded form of open types when automatically decoding open types. |
IGNORE_DEFER_DECODING | Instructs the encoder/decoder to encode/decode an open type generated with the ASN1.DeferDecoding directive along with its containing type. Thus, open types created with the ASN1.DeferDecoding directive can be automatically encoded/decoded when this flag is set and AUTOMATIC_ENCDEC is also specified. This flag is not currently supported by the TOED. |
NOCONSTRAIN | Instructs the decoder to not perform strict constraint checking at runtime for improved CPU performance during decoding. We recommend that you do not set this flag during development because strict constraint checking can help you detect coding errors. |
NOTRAPPING | Disables signal trapping by default. Also, see OSS_TRAPPING. |
OLD_STRICT_ENCODING_DECODING_RULES | Starting with version 6.6, the STRICT_ENCODING_DECODING_RULES flag enforces stricter checking of conformance to encoding rules. For compatibility with pre-6.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. The OLD_STRICT_ENCODING_DECODING_RULES flag overrides 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_SKIP_UNKNOWN_CONTENT | 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 command line option, so unknown extensions are not saved when the flag is set. |
OSS_TRAPPING | Enables signal trapping. With signal trapping on, performance suffers somewhat. More importantly, signal trapping is not always thread-safe, depending on the operating system in use. We recommend that you do not enable trapping for multi-threaded applications. In other cases, you can specify this flag to help find coding errors since, with signal trapping enabled, the OSS runtime will return an error code and message, rather than just crashing. The old NOTRAPPING flag is supported for the sake of compatibility, but OSS_TRAPPING takes precedence. That is, if both NOTRAPPING and OSS_TRAPPING are specified then trapping is enabled; if neither flag is specified then trapping is disabled. NOTE: Before release 4.1, the OSS runtime trapped signals by default. |
OSS_RELAXED (RELAXBER, RELAXPER) |
Instructs the decoder to not report an error when the input encoding slightly deviates from the ITU-T standards (the Canonical-PER decoder ignores the flag). A list of acceptable deviations follows, grouped by encoding rules. BER When BER is in use, the flag relaxes the rules for INTEGER decoding, allowing some invalid encodings to pass without an error check. Example I ::= INTEGER (0..MAX)Using the syntax above, the following encoding is passed to the BER decoder: 0x02, 0x03, 0x80, 0x00, 0x7bNormally, the decoder issues an error message that says a negative unsigned integer was encountered, which is in strict accordance with the ITU-T Standards. When the OSS_RELAXED flag is set, the decoder silently decodes the encoding as if it were 0x02, 0x04, 0x00, 0x80, 0x00, 0x7bAlso, if the first 9 bits of the encoding are all 1's or all 0's, as follows: 0x02, 0x03, 0x00, 0x00, 0x7bthe decoder normally complains that the integer value encoding is unnecessary long, which is also in strict accordance with the Standards. When the OSS_RELAXED flag is specified, the decoder silently decodes such encodings. The OSS_RELAXED flag can also disable error checks for
PER When PER is in use, the flag relaxes the rules related to the length determinant, as specified in clause 11.9 of X.691. Example Foo1 ::= VisibleStringThe following valid PER ALIGNED encoding could be generated from the syntax above: 04 6E6E6E6EThe first octet, 04, defines a contents length, which is four octets long in this case. However, some applications could incorrectly encode the length field so that the length value can still be retrieved, but the format of the length field is non-standard: 8004 6E6E6E6ENormally, the PER decoder issues an error message when receiving such an encoding, because the length determinant is encoded with too many octets. According to the ASN.1 standard, a two-octet length should be used only when the length is greater than 127. To work around such problematic encodings, use the OSS_RELAXED flag to instruct the decoder to retrieve the correct value of the length field, while ignoring its incorrect format. You can also use the OSS_RELAXED flag to instruct the decoder to accept an encoded length that is in the wrong format (i.e., it occupies more bytes than necessary) for extension additions. The OSS_RELAXED flag also can disable error checks for
E-XER When E-XER is in use, the flag instructs the E-XER decoder to silently accept input XML documents in UTF-8 encoding, even when the encoding specified by the XML declaration differs from "UTF 8" and "US-ASCII". Example <?xml version="1.0" encoding="ISO-8859-1"?><A/> Any Encoding Rules When any set of encoding rules is used, the flag instructs the decoder to
|
STRICT_ENCODING_DECODING_RULES | Enables strict checking of conformance to the encoding rules. The flag overrides the OSS_RELAXED (RELAXBER, RELAXPER) flag. When the flag is set, the following are not allowed by the decoder:
|
PRINT_DECODER_INPUT, PRINT_DECODER_OUTPUT, PRINT_DECODING_DETAILS, PRINT_ENCODER_INPUT, PRINT_ENCODER_OUTPUT, PRINT_ENCODING_DETAILS, PRINT_ERROR_MESSAGES, PRINT_HEX_WITH_ASCII
or with one of the combined "debugging level" literals:
OSS_DEBUG_LEVEL_0, OSS_DEBUG_LEVEL_1, OSS_DEBUG_LEVEL_2, OSS_DEBUG_LEVEL_3, OSS_DEBUG_LEVEL_4
The flags and the debugging levels (macros) are described in the following tables.
Flag | Description |
---|---|
PRINT_DECODER_INPUT | Print the decoder input on entry to the decoder. If the input is a binary encoding (e.g., BER or PER), printHex() is called; otherwise printXML() is called to print the input as formatted XML. This flag is not available for input from a file or socket. A descriptive comment, "The input to the decoder:", is printed before the decoder input. If the decoder input is in hexadecimal and the PRINT_HEX_WITH_ASCII flag is set, a header and footer is produced that wraps the hexadecimal and ASCII output: # Offset Stream of Octets Written in Hexadecimal Character Format # ====== ======================================= ================and # ====== ======================================= ================ |
PRINT_DECODER_OUTPUT | Print the decoder output just before the decoder exits. For the TOED, specify
-DOSSPRINT and -DOSSDEBUG=x (where x is 1 or more, e.g., -DOSSDEBUG=2) when compiling the generated TOED code. A descriptive comment, "The decoder output:", is printed before the decoder output. |
PRINT_DECODING_DETAILS | Print verbose trace messages while decoding. This flag is not available for the TOED and LED libraries. A descriptive comment, "The decoder trace messages:", is printed before the decoder trace. |
PRINT_ENCODER_INPUT | Print the encoder input on entry to the encoder. For the TOED, specify
-DOSSPRINT and -DOSSDEBUG=x (where x is 1 or more, e.g., -DOSSDEBUG=2) when compiling the generated TOED code. A descriptive comment, "The input to the encoder:", is printed before the encoder input. |
PRINT_ENCODER_OUTPUT | Print the encoder output just before the decoder exits. If the output is a binary encoding (e.g., BER or PER), printHex() is called; otherwise printXML() is called to print the output as formatted XML. This flag is not available for output from a file or socket. A descriptive comment, "The encoder output:", is printed before the encoder output. If the encoder output is in hexadecimal and the PRINT_HEX_WITH_ASCII flag is set, a header and footer is produced that wraps the hexadecimal and ASCII output: # Offset Stream of Octets Written in Hexadecimal Character Format # ====== ======================================= ================and # ====== ======================================= ================ |
PRINT_ENCODING_DETAILS | Print verbose trace messages while encoding. This flag is not available for the TOED and LED libraries. A descriptive comment, "The encoder trace messages:", is printed before the encoder trace. |
PRINT_ERROR_MESSAGES | Causes functions that can print error messages (e.g., encode(), decode()) to print a message when an error occurs. For the TOED, specify
-DOSSDEBUG=x (where x is 1 or more, e.g., -DOSSDEBUG=2) when compiling the generated TOED code. One of the following descriptive comments is printed before the error message: The encoder error message:or The decoder error message: |
PRINT_HEX_WITH_ASCII | Causes printHex() to print an ASCII translation of its input buffer on the right, with '.' substituted for unprintable characters. Following is a sample output:
# 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 # 000020: 6869 7274 4788 7469 6502 8874 6965 6290 hirtG.tie..tieb. # 000030: 7368 6972 74C7 9073 6869 7274 6A00 shirt..shirtj.This flag affects the printHex() behavior no matter how it is called: explicitly by you or implicitly by the OSS runtime when the PRINT_ENCODER_OUTPUT or PRINT_DECODER_INPUT debugging flag is processed. |
The following macros define diagnostic levels by combining the debug flags above into five commonly used groups.
Macro | Description |
---|---|
OSS_DEBUG_LEVEL_0 | No diagnostics are printed by the encoder/decoder. If -DOSSDEBUG=x (where x is 1 or more, e.g., -DOSSDEBUG=2), is specified for the TOED, or if the SOED library is in use, a diagnostic message is created but not printed. This level is the default. |
OSS_DEBUG_LEVEL_1 | Causes functions that can print error messages (e.g., encode(), decode()) to print a message when an error occurs. For the TOED, specify -DOSSDEBUG=x (where x is 1 or more) when compiling the generated TOED code. |
OSS_DEBUG_LEVEL_2 | This macro has the same effect as OSS_DEBUG_LEVEL_1, but also prints the encoder input on entry to the encoder and the decoder output just before the decoder exits. For the TOED, specify -DOSSPRINT when compiling the generated TOED code. |
OSS_DEBUG_LEVEL_3 | This macro has the same effect as OSS_DEBUG_LEVEL_2, but also prints the encoder output before exiting the encoder and the decoder input on entry to the decoder. |
OSS_DEBUG_LEVEL_4 | This macro has the same effect as OSS_DEBUG_LEVEL_3, but also causes the encoder and decoder to print verbose trace messages. This is not available for the TOED or LED libraries. For binary encodings (e.g., BER and PER), an ASCII translation of the encoder output and the decoder input is produced on the right, with '.' substituted for unprintable characters (instead of a HEX dump). |
PRINT_DECODER_INPUT, PRINT_DECODER_OUTPUT, PRINT_DECODING_DETAILS, PRINT_ENCODER_INPUT, PRINT_ENCODER_OUTPUT, PRINT_ENCODING_DETAILS, PRINT_ERROR_MESSAGES, PRINT_HEX_WITH_ASCII
or one of the combined 'debugging level' literals:
OSS_DEBUG_LEVEL_0, OSS_DEBUG_LEVEL_1, OSS_DEBUG_LEVEL_2, OSS_DEBUG_LEVEL_3, OSS_DEBUG_LEVEL_4
For details about these flags, see the description of the setDebugFlags() method.
OSS_V85_TABLE_CONSTRAINT_FOR_EXTENSIBLE_OBJECT_SETS, OSS_ALLOW_MISPLACED_EXTENSION_FIELDS, OSS_ALLOW_NON_NR3_DER_REAL, OSS_ALLOW_NULL_IN_TIME, OSS_PACK_WIDE_STRINGS, OSS_EXTENDED_RESTRICTED_KMC_STRING_AS_OCTETS, OSS_PER_ALLOW_TRAILING_ZEROS, OSS_PER_NULLTERM_TIME_8BIT_CHARS OSS_USE_TYPE_IDENTIFICATION_ATTRIBUTE_FOR_UNION
A detailed description of these flags can be found in the setCompatibilityFlags() section below.
This example uses the method and tests the flag:
OssControl ctl; unsigned long ret_flag = ctl.getCompatibilityFlags(); if (ret_flag < 0) { ... error condition ... } if (ret_flag & OSS_PACK_WIDE_STRINGS) { ... OSS_PACK_WIDE_STRINGS flag is set ... } else { ... OSS_PACK_WIDE_STRINGS flag is not set ... }
NOTE: OSS does not guarantee compatibility between different versions of the ASN.1 Tools released more than 10 years apart.
The parameter is a bitmask of an unsigned long type and can be one of the following flags, or a combination of these flags created with a bitwise OR (i.e., separated by a vertical bar: "|"):
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_V85_TABLE_CONSTRAINT_FOR _EXTENSIBLE_OBJECT_SETS |
Applies only to the SOED/LED runtime. Prior to version 4.3.1, the OSS Constraint Checker mishandled table/component relation constraint violations for extensible object sets. Starting with version 4.3.1, the OSS ASN.1/C++ Compiler and Runtime support X.681 Annex E.2. That is, a constraint violation error is reported if table/component relation constraints are not satisfied for an extensible object set and any of these conditions is true:
|
OSS_ALLOW_MISPLACED_EXTENSION _FIELDS |
Applies only to the SOED/LED BER decoder. Using this flag forces the decoder into relaySafe mode to accept an unknown extension field that is illegally located after additional root fields in the input encoding. Otherwise, the encoding is considered invalid and the decoder issues the "D0047E: Tag not recognized" error message. |
OSS_ALLOW_NON_NR3_DER_REAL | Applies to the DER, CER and PER encoder. Using this flag directs the encoder to skip NR3 normalization of decimal REAL types, as was done in pre-4.0 versions of the OSS ASN.1/C++ Tools. |
OSS_ALLOW_NULL_IN_TIME | Applies to the BER Time-Optimized decoder only. The decoder issues an error if the encoding of a GeneralizedTime type value contains superfluous trailing NULL octets. Specify the OSS_ALLOW_NULL_IN_TIME flag (via setCompatibilityFlags()) to force the decoder to silently ignore such octets in a BER encoding. |
OSS_OLD_UTF8_CHECK | Available for the LEAN/SOED/TOED runtimes. Provides compatibility with pre-6.6 versions. Starting with version 6.6, the runtimes report errors on the following illegal UTF8 characters:
|
OSS_PACK_WIDE_STRINGS | Applies only to the PER Space-Optimized Encoder/Decoder. This means that wide string characters with permitted alphabet constraints are encoded relative to the zero value of the lowest cell in the permitted alphabet, not to the lowest value in the cell. In the following example, this flag causes value a to be encoded as 0x0140 instead of 0x0120 in aligned PER, as though the permitted alphabet is FROM({0,0,30,0}..{0,0,30,127}). A ::= BMPString (FROM({0,0,30,32}..{0,0,30,127})) a A ::= {0,0,30,64} |
OSS_EXTENDED_RESTRICTED_KMC _STRING_AS_OCTETS |
Applies only to the PER encoder/decoder. Using this flag forces the encoder/decoder to ignore PermittedAlphabet in extensible KMC string types if the actual string length exceeds that of the extension root. In this regard, the flag restores the behavior of pre-4.0 versions of the OSS ASN.1/C++ Tools. |
OSS_INTERVAL_FRACTION_1_999 | Applies only to the PER runtime. Using this flag causes the encoding of a DURATION-INTERVAL fractional value to be
INTEGER (1..999, ..., 1000..MAX) instead of INTEGER (0..999, ..., 1000..MAX)See Corrigendum 4 to clause 32.6.1 of the X.691 standard. |
OSS_NO_DETAIL_MM_ERROR_CODES | Applies only to the Space-Optimized Encoder/Decoder (SOED). Prior to version 6.0, OSS methods returned the FATAL_ERROR (18) common error code and the
x0087S: Undefined memory-management error #Nmessage when errors specific to EncodedFile/EncodedSocket objects occurred, such as an error reading from or writing to a file/socket. Starting with version 6.0, more error codes and messages are returned in this case. Using this flag restores the old behavior. |
OSS_PER_ALLOW_TRAILING_ZEROS | Applies to the PER Space-Optimized encoder only. Starting with version 4.3, the encoder strips trailing zeros from an encoded BITSTRING with named bits according to Clause 15.2 of X.691. Previously, such bits were encoded. In this regard, the flag restores the behavior of pre-4.3 versions of the OSS ASN.1/C++ Tools. |
OSS_PER_NULLTERM_TIME_8BIT_CHARS | Applies only to the PER encoder/decoder. Using this flag forces the encoder/decoder to handle unaligned PER encodings of UTCTime and GeneralizedTime types as though 8 bits per character are used, which makes them identical to an aligned PER encoding. In this regard, the flag restores the behavior of pre-4.0 versions of the OSS ASN.1/C++ Tools. |
OSS_TRUNCATE_0_SECONDS_FROM _GENERALIZED_TIME |
Applies only to the Space_Optimized DER and PER encoders. Using this flag causes trailing zeros after the seconds field in GeneralizedTime type encodings to be truncated, e.g., 1998120311235500 is truncated to 19981293112355. |
OSS_TRUNCATE_0_SECONDS_FROM _UTC_TIME |
Applies only to the SOED DER and PER encoders. Using this flag causes trailing zeros after the seconds field in UTCTime type encodings to be truncated, e.g., 98120311235500Z is truncated to 981203112355Z. |
OSS_USE_TYPE_IDENTIFICATION _ATTRIBUTE_FOR_UNION |
Applies only to the Space_Optimized and Lean E-XER encoders. Using this flag allows the encoder to generate a type identification attribute for a choice type with a USE-UNION encoding instruction, if the type has a final UNTAGGED encoding instruction. |
This example sets the compatibility flag:
OssControl ctl; ctl.setCompatibilityFlags(OSS_ALLOW_MISPLACED_EXTENSION_FIELDS);
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 never 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, if the flag is not specified, the COPYRIGHT SIGN character is UTF-8 encoded into two octets, 0xC2 and 0xA9. If the flag is set, it is encoded using the unicode escape sequence \u00A9. |
JSON_COMPACT_ENCODING | Instructs the JSON encoder to create a compact JSON encoding with no whitespace or new lines. When the flag is not specified, the encoder inserts whitespace and newlines to improve readability. |
JSON_WRAPPED_ENCODING | Instructs the encoder to create a wrapped JSON encoding of outermost types. By default, an unwrapped JSON encoding is created. |
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.
The following example uses this flag:
MyASN1DataType_PDU pdu; OssControl ctl; ... if ( ctl.getEncodingRules() == OSS_JSON) { ctl.setJsonFlags(ctl.getJsonFlags() | JSON_ENC_CONTAINED_AS_TEXT); pdu.encode(ctl); }For the following syntax the OCTET STRING value A ::= SEQUENCE { opaque OCTET STRING (CONTAINING SEQUENCE { name UTF8String, age INTEGER }) } v A ::= { opaque CONTAINING { name "John", age 33 } }is encoded as a hex string: { "opaque":"7B0A2020226E616D65223A224A6F686E222C0A202022616765223A33330A7D" }When the JSON_ENC_CONTAINED_AS_TEXT runtime flag is set, it is encoded in the expanded form: { "opaque":{ "containing":{ "name":"John", "age":33 } } } |
JSON_ENC_ABSENT_COMPONENTS, JSON_ENC_DEFAULT_VALUES, JSON_USE_UNICODE_ESCAPE_SEQUENCE, JSON_COMPACT_ENCODING JSON_WRAPPED_ENCODING JSON_ENC_CONTAINED_AS_TEXTA detailed description of these flags can be found in the setJsonFlags() section.
OssControl ctl; unsigned long ret_flag = ctl.getJsonFlags(); if (ret_flag == (unsigned long)-1) { ... error condition ... } if (ret_flag & JSON_COMPACT_ENCODING) { ... JSON_COMPACT_ENCODING flag is set ... } else { ... JSON_COMPACT_ENCODING flag is not set ... }
The class derived from OssControl and generated by the compiler is referred to as <projectname>_Control. This class represents control objects that are tailored to use a particular specification. Instantiate this class directly. <projectname> represents the ASN.1 specification file name, not the module name. In other words, for myfile.asn, the myfile_Control class is generated. By default, <projectname> coincides with the last ASN.1 filename specified on the command line. The name of the generated class and the generating filename can be altered using the ASN.1/C++ Compiler options.
asn1_clean_error(); bcas_Control ctl; if (asn1_get_last_error()) { printf("OssControl object was not created. " "Error code is: %d\n", asn1_get_last_error()); return 1; }See ASN.1/C++ Encoder/Decoder Return Codes for information about error codes returned by asn1_get_last_error().
Many functions that take an OssControl object as an argument output some text information. For example, the print() method of a PDU object prints the textual representation of the object in the ASN.1 value notation format, the encoding/decoding function can print diagnostic output, and the OssControl class printHex() utility method prints a hexadecimal dump of a memory block.
By default, all these functions output information to standard output. (If the platform does not support the standard output concept, as with some embedded systems, it outputs information to some other designated place.) However, there could be situations when this is undesirable. The ASN.1/C++ API provides the necessary means to redirect this output to another destination.
To simply redirect this output to a file, use the setOutputFile() function. However, this may not always be sufficient; e.g., the desired destination is not a file but a screen window, or special formatting or filtering should be applied to the output. The ASN.1/C++ API gives you the ability to redirect the output to an arbitrary function.
To achieve this, derive a new class from the control class generated by the ASN.1/C++ compiler. Provide a new implementation of the virtual userPrint() function in the new class, which will be called when the runtime is about to print a string. This function allows you to determine the format of what is printed.
The encoder/decoder can encode/decode data to/from a memory block, a file, or a socket. These encoded data sources are represented by the EncodedBuffer, EncodedFile, or EncodedSocket classes respectively. These three classes are derived from the common ancestor, the EncodedData class. EncodedData is an abstract class. Thus, the methods described in this section should be applied to instances of the EncodedBuffer, EncodedFile, or EncodedSocket classes.
Relationship between the EncodedData class and its sub-classes
class EncodedData { public: void enableSkipPadBytes(unsigned char pad_byte); void disableSkipPadBytes(); };
The EncodedBuffer class is a subclass of EncodedData. The encoded data is stored in memory. An EncodedBuffer object can be in one of these three states:
Similar to the file pointer concept, EncodedBuffer has a current buffer pointer concept: it always points to the next available location for encoding or decoding data. A call to the encoding/decoding functions advances the current pointer, so that a subsequent encoding or decoding reads or writes data in the adjacent memory location. This allows the user to easily encode several PDUs into one preallocated buffer, as well as to decode several PDUs from one buffer. Changing the buffer mode from encoding to decoding, or vice versa, resets the current pointer to the beginning of the buffer.
EncodedBuffer has two different concepts of length: buffer size and information size. Buffer size is the total number of bytes that was allocated to the buffer in memory. Information size is the number of bytes that is used for storing the encoded information. The sizes can differ since some part of the buffer could be currently unoccupied.
The EncodedBuffer class supports encoding of several concatenated PDUs into one preallocated buffer. This feature is available only when the encoder is set to front-align mode. If the encoder is in back-align or in default mode, an attempt to encode another PDU into an occupied buffer will cause an error. See OssControl Class Methods for more information on the encoder/decoder alignment modes.
If the EncodedBuffer that was passed as a parameter is initialized with either an automatically allocated or a preallocated buffer, this buffer is used when encoding. If the EncodedBuffer is in input mode (i.e., the last coding operation performed on it was reading from the buffer), then the current pointer is reset to the beginning of the buffer, the information size is reset to 0, and encoding starts from the beginning of the buffer (or from its end, depending on the encoder data alignment mode). Otherwise, encoding starts at the current pointer so that the data placed in the buffer by the previous decode operations are preserved. If there is no room to hold the encoded data in the buffer, an error is returned. If the EncodedBuffer is uninitialized, a buffer that can hold the encoded data is automatically allocated. The encoded data will be placed at its beginning. If the encoding process is successful, the current pointer is moved to the point immediately following the encoded data and the information size is incremented by the encoded data length.
The EncodedBuffer class supports decoding of several concatenated PDUs from one preallocated buffer. If the EncodedBuffer that was passed as a parameter is uninitialized, an error occurs. If the EncodedBuffer is in output mode (i.e., the last coding operation performed on it was writing to the buffer), the current pointer is reset to the beginning of the buffer, so that decoding starts from the beginning. Otherwise, decoding starts at the current pointer. If the current pointer offset is larger than the information size (i.e., there is no more information in the buffer to decode), an error occurs. If the decoding process is successful, the current pointer is advanced accordingly.
ASN.1/C++ supports decoding into a preallocated memory buffer. In this case, the buffer of the EncodedBuffer object is used as output storage for the decoded value. Also, the decoding operation can be significantly faster than the usual decoding to dynamic memory. See PDU Class Methods for a detailed description. When decoding into a preallocated memory buffer, two EncodedBuffer objects are involved in the operation. The EncodedBuffer object containing the encoding is set to input mode as usual, so it acts as described in EncodedBuffer Decoding Behavior. The EncodedBuffer object used as storage for the decoded object is set to output mode, so it acts as described in EncodedBuffer Encoding Behavior.
class EncodedBuffer: public EncodedData { public: EncodedBuffer(); EncodedBuffer(unsigned long length, char *value); EncodedBuffer(OssString & any); ~EncodedBuffer(); void set_buffer(unsigned long length, char *value); void grab_buffer(unsigned long length, char *value); void clone(EncodedBuffer & orig); char *get_data() const; char *release_data(); unsigned long get_length() const; unsigned long get_data_size() const; unsigned long get_data_offset() const; unsigned long get_position() const; int set_position(unsigned long pos); int is_preallocated() const; int print_hex(OssControl & ctl) const; void print_xml(OssControl & ctl, int pretty_print) const; void reset(); void print_json(OssControl & ctl, int pretty_print) const; };
set_buffer(0, NULL);deallocates the present buffer and resets the object to the uninitialized state.
The PEREncodedBuffer class is a subclass of EncodedBuffer. PER encodings can consist of an arbitrary number of bits, not necessarily an integral number of octets. You might need to determine how many bits in the last byte of the encoding are unused. The EncodedBuffer class lacks such functionality; it is implemented in the PEREncodedBuffer class.
PER is not required to use the PEREncodedBuffer class. It can also be used with any other encoding rules, in which case, the number of padding bits will be always 0. You might choose this variant, for example, when the application dynamically changes the encoding rules in use; just be sure to write generic code that works for every possible set of encoding rules.
class PEREncodedBuffer : public EncodedBuffer { public: PEREncodedBuffer(); PEREncodedBuffer(unsigned long length, char *value); PEREncodedBuffer(OssString & any); void set_buffer(unsigned long length, char *value); void grab_buffer(unsigned long length, char *value); int get_pad_bits() const; void clone(EncodedBuffer &orig); void set_position(unsigned long pos); };
The EncodedFile class is a subclass of EncodedData. The encoded data is stored in a file. The Lean Encoder/Decoder (LED) and the Time-Optimized Encoder/Decoder (TOED) do not support encoding to or decoding from files without using intermediate memory buffers, so use the SOED to take advantage of this class. Alignment flags are ignored when encoding/decoding to/from a file or socket; front alignment is always used.
class EncodedFile: public EncodedData { public: EncodedFile(const char *filename, int append = 0); ~EncodedFile(); void reset(); };
The EncodedSocket class is a subclass of EncodedData. The encoded data is read from or written to a socket. The Lean Encoder/Decoder and the Time-Optimized Encoder/Decoder do not support encoding to or decoding from sockets without using intermediate memory buffers, so use the SOED to take advantage of this class. Alignment flags are ignored when encoding/decoding to/from a file or socket; front alignment is always used.
NOTE: The behavior of OSS methods when encoding and decoding data using the EncodedSocket class is based on the send() and recv() socket functions and therefore is inherited from these socket functions. For example, when a socket is closed by the remote side and a subsequent send() on the local side does not report an error, an OSS encode() would also be unable to detect the closed socket and instead would accept the undeliverable packet. You can use the handler of the socket you pass to the EncodedSocket constructor to tune the socket, or to send or receive additional messages using socket functions.
class EncodedSocket: public EncodedData { public: EncodedSocket(SOCKET socket); ~EncodedSocket(); };
This class acts as a common ancestor for all generated coding classes. To perform some action (e.g.,encoding, decoding, printing, constraint-checking) on a representation type value, the application programmer must use an object of the appropriate coding class. A coding class object acts as a container for the corresponding representation type. Each coding class includes a pointer to the related representation object. The object pointed to can be constant, however, it cannot be modified by any of the ASN1Handle methods or their successors.
NOTE: The representation object is owned by the caller, that is, it is not destroyed by the ASN1Handle object destructor. The destruction of the representation object is the responsibility of the caller.
The ASN1Handle class itself represents a non-PDU type and has no encoding/decoding functions, they are provided by its successor PDU. However, it can be used to print the contents of representation class objects, to check constraints, or to convert corresponding representation type values to/from ASN.1 value notation. When the program deals with several ASN.1 specifications at the same time, make sure to use ASN1Handle (and OssControl) objects only with the representation objects produced from the corresponding specification. Errors that arise from specification mismatches are not trapped.
Relationship between the ASN1Handle class and its sub-classes
class ASN1Handle { public: int print(OssControl &ctl) const; char *toString(OssControl &ctl, char *buffer = NULL, unsigned long length = 0) const; unsigned long toStringLength(OssControl &ctl) const; int check_constraints(OssControl &ctl) const; int setFromValueNotation(OssControl &ctl, const char *valnot); char *asValueNotation(OssControl &ctl) const; void release_data(); int copy(OssControl &, const ASN1Handle &); int equals(OssControl &, const ASN1Handle &) const; int free_data(OssControl &); int is_constant() const; };
delete pdu.get_data();
or
pdu.free_data(ctl);
Use the first way when the PDU object contains a class instance. However, if the contained ASN.1 type is represented by a primitive C++ type such as int, you must use another form (instead of delete):
asn1Free(pdu.get_data());
The second way (calling free_data) is correct regardless of the contained ASN.1 type.This abstract class is derived from ASN1Handle; it acts as a common ancestor for all generated PDU types and presents encoding and decoding methods.
class PDU: public ASN1Handle { public: int encode(OssControl &ctl, EncodedData &buf) const; int decode(OssControl &ctl, EncodedData &buf); int decode(OssControl &ctl, EncodedData &input, EncodedBuffer &output); long determineEncodingLength(OssControl &ctl) const; int binary2XML(OssControl &ctl, OssEncodingRules rule, EncodedData &from, EncodedData &to); int XML2Binary(OssControl &ctl, OssEncodingRules rule, EncodedData &from, EncodedData &to); int binary2JSON(OssControl &ctl, OssEncodingRules rule, EncodedData &from, EncodedData &to); int JSON2Binary(OssControl &ctl, OssEncodingRules rule, EncodedData &from, EncodedData &to); int convertData(OssControl &ctl, EncodedBuffer &fromData, unsigned int fromFormat, EncodedBuffer &toData, unsigned int toFormat); };
The binary2XML(), XML2Binary(), binary2JSON(), and JSON2Binary() methods perform the conversions by decoding and then re-encoding the input message. Starting with version 7.0, the methods check if, at the 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.
This class is derived from the PDU class; it acts as a common ancestor for all generated specific PDU types; see Specific PDU Class <Typename>_PDU for details.
class ConcretePDU: public PDU { public: int decode(OssControl &ctl, EncodedData &buf); int decode(OssControl &ctl, EncodedData &input, EncodedBuffer &output); int partialDecode(OssControl &ctl, EncodedData &buf, OssCallback &callback); int partialDecode(OssControl &ctl, EncodedData &buf, OssCallback &callback, EncodedBuffer &dst); };
The OssCallback class is a base interface that is defined in the asn1.h file:
/* a class used as an interface by ConcretePDU::partialDecode */ class PUBLIC OssCallback { public: void * userVar; };
To pass data between the application and the callback methods or between callback method calls, use the userVar(void *) member within the OssCallback class. If the data to be passed fits the pointer size, it can be stored directly in the field. Otherwise, the field can store a pointer to the memory block that contains the data.
General information about partial decoding can be found in Partial Decoding.
When -enablePartialDecode or -partialDecodeOnly is specified, the ASN.1/C++ Compiler generates a subclass of the OssCallback interface that contains the default implementation of the callback method:
int <MethodName>(OssGlobal *_g, long offset, long length, unsigned int flags, Tvalue *value);
MethodName | is the user-defined name for the callback method. |
_g | is a pointer to the OssGlobal structure, which is used internally by the ASN.1/C++ API and never modified by the user application. |
offset | is the offset (in bytes) of the field. |
length | is the length (in bytes) of the field encoding. |
flags | indicates situations where it would be impossible 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 | is a pointer to the decoded value. |
The _g, offset, length, and flags parameters are the same for all callback methods. The value parameter points to the decoded value of the field to which the directive is applied. Its actual type varies depending on the ASN.1 type. The decoded value is available only in the callback method.
The decoder reuses the memory allocated for the value after the callback method returns. Therefore, the callback member function code should store the decoded field value for future use, if necessary. Reusing memory like this significantly reduces the amount of memory needed for decoding. For example, if the OSS.DataCallback directive is applied to an element of a SEQUENCE OF type, the decoder will not allocate more memory than needed for one element.
The following flags can be passed to the callback method:
Instruct the decoder to either stop or continue decoding the message by means of a return code from your callback method.
Any other return code from the callback method signals an error to the decoder, in which case the decoder executes a longjmp() and ConcretePDU::partialDecode() returns the return code it received from the callback method. Note that returning via longjmp() is often slower than using OSS_SKIP_TO_PDU_END to skip to the end.
The ASN.1/C++ Compiler generates the class that contains the callback methods, so you can easily derive the class and implement the methods.
ASN.1 syntax (bcas.asn):
--<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 derived class from the syntax above:
/* Partial decoding callback class */ class OSS_PUBLIC bcas_Callback : public OssCallback { public: /* user-defined data callback method for ASN.1 item(s) BCAS.BBCard.age */ virtual int myFunc(OssGlobal *_g, long offset, long length, unsigned int flags, OSS_UINT32 *value); };
The next example shows you how to derive the compiler-generated class and how to call the ConcretePDU::partialDecode() API. For the sake of readability, exception handling code is omitted from this example.
/* the BER encoding of a BBCard PDU */ char ber_enc[] = { 0x30, 0x34, 0x1A, 0x05, 0x43, 0x61, 0x73, 0x65, 0x79, 0x02, 0x01, 0x20, 0x1A, 0x0A, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x66, 0x69, 0x65, 0x6C, 0x64, 0x30, 0x1C, 0x30, 0x1A, 0x02, 0x02, 0x07, 0xD0, 0x02, 0x02, 0x07, 0xD6, 0x1A, 0x10, 0x4E, 0x65, 0x77, 0x20, 0x59, 0x6F, 0x72, 0x6B, 0x20, 0x59, 0x61, 0x6E, 0x6B, 0x65, 0x65, 0x73 }; /* User-defined callback class */ class myCallbackClass : public bcas_Callback { public: int myFunc(OssGlobal *_g, long offset, long length, unsigned int flags, OSS_UINT32 *value); }; /* User-implemented callback method */ int myCallbackClass::myFunc(OssGlobal *_g, long offset, long length, unsigned int flags, OSS_UINT32 *value) { ossPrint(_g, "Age field value is: %d", *value); return OSS_CONTINUE_DECODING; }; /* Invocation of ConcretePDU::partialDecode() method */ void testDataCallback() { BBCard_PDU pdu; bcas_Control ctl; EncodedBuffer eb; myCallbackClass cback; ctl.setEncodingRules(OSS_BER); eb.set_buffer(sizeof(ber_enc), ber_enc); pdu.partialDecode(ctl, eb, cback); }
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 on the field and on the encoding rules employed, as follows:
Regardless, the pointer to the current position is advanced to the subsequent field. If the field to be skipped is a constructed type that contains a field marked with the OSS.DataCallback directive, it cannot be entirely skipped and the procedure applies recursively.
NOTE: During partial decoding, when the decoder is able to skip a field by jumping over it, it does not stop to examine the contents. Such skipped fields are not checked for adherence to the encoding rules.
When an OSS.DataCallback directive is applied to a type that occurs in multiple locations and the OSS.InfoCallback directive is also specified, the following method is added to the generated callback class:
int(OssGlobal *_g, const char *fname, unsigned int flags);
MethodName | is the user-defined name for the callback method. |
_g | is a pointer to the OssGlobal structure, which is used internally by the ASN.1/C++ API and never modified by the user application. |
fname | is the name of the field being decoded. |
flags | indicates the decoding status of the current field. Only the OSS_DECODING_OF_COMPONENT_IN_PROGRESS value can be set. |
Possible return values and how the ASN.1 C++ Runtime handles them are the same as those of the data callback method.
OSS.InfoCallback usage is illustrated in the following example.
ASN.1 syntax (infotest.asn):
M DEFINITIONS AUTOMATIC TAGS ::= BEGIN Subscriber ::= SEQUENCE { name VisibleString, company Company, homeAddress Address } Company ::= SEQUENCE { name VisibleString, address Address } Address ::= SEQUENCE { zipcode INTEGER( 0..99999 ), addressline VisibleString( SIZE (1..64) ) } END
When the directive is applied to the zipcode field in the ASN.1 syntax above
--<OSS.DataCallback M.Address.zipcode "myZipcode">--
then the myZipcode() callback method is called for zipcode in both uses of Address.
To filter out the zipcode values, use the OSS.InfoCallback directive:
--<OSS.InfoCallback M.Subscriber.homeAddress "homeAddressField">--
This directive instructs the compiler to generate a prototype for the homeAddressField() callback method inside the <module_name>_Callback class. This method is called by the decoder twice: once before starting the partial decoding of the homeAddress field and again after finishing its decoding. Note that the decoder only informs the application about a particular step of the decoding process. It does not pass any decoded values to the method, thus the info callbacks are faster than the data callbacks.
The following example illustrates how data and info callback methods can be combined so that only zipcode values from homeAddress are processed and zipcode values from companyAddress are ignored.
/* the BER encoding of a Subscriber PDU */ char ber_enc[] = { 0x30, 0x5D, 0x80, 0x08, 0x4A, 0x6F, 0x68, 0x6E, 0x20, 0x44, 0x6F, 0x65, 0xA1, 0x2D, 0x80, 0x10, 0x41, 0x62, 0x73, 0x75, 0x72, 0x64, 0x20, 0x4C, 0x6F, 0x67, 0x69, 0x73, 0x74, 0x69, 0x63, 0x73, 0xA1, 0x19, 0x80, 0x02, 0x30, 0x39, 0x81, 0x13, 0x38, 0x30, 0x30, 0x2C, 0x20, 0x37, 0x74, 0x68, 0x20, 0x53, 0x74, 0x72, 0x65, 0x65, 0x74, 0x2C, 0x20, 0x4E, 0x59, 0xA2, 0x22, 0x80, 0x03, 0x01, 0x09, 0x32, 0x81, 0x1B, 0x33, 0x33, 0x33, 0x2C, 0x20, 0x46, 0x6F, 0x6F, 0x62, 0x61, 0x72, 0x20, 0x44, 0x72, 0x2E, 0x2C, 0x20, 0x42, 0x61, 0x79, 0x6F, 0x6E, 0x6E, 0x65, 0x20, 0x4E, 0x4A }; /* A structure for data exchange between callback function calls. In case of multithreading it should be allocated per thread */ typedef struct { int flag; } UserData; UserData data; /* derive the compiler generated infotest_Callback class */ class myCallbackClass : public infotest_Callback { public: int myZipcode(OssGlobal *_g, long offset, long length, unsigned int flags, OSS_UINT32 *value); int homeAddressField(OssGlobal *_g, const char *fname, unsigned int flags); }; /* Info callback method. It sets the flag indicating that homeAddress field is being decoded */ int myCallbackClass::homeAddressField(OssGlobal *_g, const char *fname, unsigned int flags) { UserData *udP = (UserData *)this->userVar; if (flags & OSS_DECODING_OF_COMPONENT_IN_PROGRESS) { ossPrint(_g, "\n\nDecoding of homeAddressField started..."); udP->flag = 1; } else { ossPrint(_g, "\nDecoding of homeAddressField completed.\n\n"); udP->flag = 0; } return OSS_CONTINUE_DECODING; } /* myZipcode callback method implementation. it prints the value of zipcode field */ int myCallbackClass::myZipcode(OssGlobal *_g, long offset, long length, unsigned int flags, OSS_UINT32 *value) { UserData *udP = (UserData *)this->userVar; ossPrint(_g, "\n!myZipcode() callback...\n"); if (udP->flag != 1) { /* we are not in homeAddress */ ossPrint(_g, " we are not in homeAaddress! Continue decoding...\n"); return OSS_CONTINUE_DECODING; } /* Print homeAddress zipcode */ ossPrint(_g, " zipcode value is %05d\n", *value); return OSS_SKIP_TO_PDU_END; }; void testInfoCallback() { Subscriber_PDU pdu; infotest_Control ctl; EncodedBuffer eb; myCallbackClass cback; cback.userVar = &data; ctl.setEncodingRules(OSS_BER); eb.set_buffer(sizeof(ber_enc), ber_enc); pdu.partialDecode(ctl, eb, cback); }
Here is the output of the code sample:
!myZipcode() callback... we are not in homeAddress! Continue decoding... Decoding of homeAddressField started... !myZipcode() callback... zipcode value is 67890
NOTE: The above code sample is provided only for illustrative purposes. In a real-life situation, the flag in the sample code would need only one bit so that, instead of using the field as a pointer to the user data, it could be directly stored in the cback.userVar field.
This documentation applies to release 7.0 and later of the OSS® ASN.1 Tools for C++.
Copyright © 2021 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.