|
Overview |
Classes and Methods |
Return Codes |
Runtime Errors |
Advanced Topics |
Program Examples
Contents
Code files generated for the Time-Optimized Encoder/Decoder contain a number of features that are either enabled or disabled by default. These features can be adjusted using C++ preprocessor macros during C++-compilation to optimize your application's performance and memory footprint. Most C++ compilers do this via the -D C++ compiler option (e.g., cc -DOSSDEBUG).
The partial decoding feature can be used instead of, or in addition to standard (full) decoding. Partial decoding allows you to
For each decoded field, the offset, length, and value are provided by the decoder to the user application via callback methods. This means that you don't need to write code or know the PDU's C++ representation details to access a deeply nested field.
Your callback method can analyze a decoded value and, by setting the return code, instruct the decoder to terminate or continue decoding.
The ASN.1/C++ Compiler generates the <module_name>_Callback class that contains your callback methods (virtual member functions); you can easily derive the class and implement the callback methods. The <module_name>_Callback class is a subclass of the OssCallback base interface.
The partial decoding feature requires the ASN.1/C++ TOED Runtime version 6.2 or later.
The BER, DER, PER, UPER, CPER, CUPER, OER, and COER binary encoding rules support partial decoding. XER, CXER, E-XER, and JSON encoding rules do not support partial decoding.
This example shows 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 result of the OSS.DataCallback directive is that myZipcode() is called for zipcode in both uses of Address. Next, the OSS.InfoCallback directive applies a filter so only the zipcode values from homeAddress are used.
ASN.1 syntax (infotest.asn):
--<OSS.DataCallback M.Address.zipcode "myZipcode">--
--<OSS.InfoCallback M.Subscriber.homeAddress" homeAddressField">--
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
Subscriber PDU encoding:
/* 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
};
Generated .cpp:
/*
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
For more details about this example, see Effect of OSS.InfoCallback.
Note: Partial decoding is a chargeable feature in non-evaluation licenses. Contact Sales to obtain pricing information.
The Time-Optimized Encoder (TOED) supports the Comma-Separated Value encoding rules (CSV). The -csv compiler option instructs the compiler to generate encoding code for CSV. When the OSS_CSV rules are set by the OssControl::setEncodingRules() API call, the PDU::encode() function encodes an in-memory PDU value to this format.
The Comma-Separated Value encoding rules (CSV) are currently supported only by the TOED runtime (excluding RTOED). The -csv compiler option is not compatible with the -soed or -rtoed option.
The CSV encoder flattens a structured ASN.1 message into a fixed number of columns by recursively expanding complex SET, SEQUENCE, and CHOICE types up to the innermost fields with simple ASN.1 types. The resulting record includes a place for each simple type value, which can be empty for optional fields with absent values or CHOICE alternatives that were not selected.
Two CSV formats are supported:
The CSV format can include an optional CSV header that is created by parsing the input PDU type definition. The header record consists of absolute references or single names that match the values in the columns (in case of a row format) or rows (in case of a column format) where each node is separated by an underscore ('_') by default or by one of the following header separators: dash ('-'), period ('.'), slash ('/'), backslash ('\').
ASN.1:
PersonnelRecord ::= SEQUENCE {
name PrintableString,
number INTEGER OPTIONAL,
children SEQUENCE OF ChildInformation
}
ChildInformation ::= SET {
name PrintableString,
date GeneralizedTime OPTIONAL
}
value PersonnelRecord ::= {
name "Nancy",
number 20,
children {
{name "James", date "20020312000000"},
{name "Martha", date "20100820000000"}
}
}
CSV row format:
name,number,children_name,children_date "Nancy",20,"James",20020312000000 "Nancy",20,"Martha",20100820000000
CSVs are in human-readable format similar to ASN.1 value notation. The table below shows the differences sorted by ASN.1 type. Additional CSV representations are available by passing special flags to the OssControl::setCsvFlags() function.
| ASN.1 Type | ASN.1 Value | CSV Value |
|---|---|---|
| BIT STRING | bstring '0101011'B |
xmlbstring 010101 |
| BOOLEAN | TRUE or FALSE | Default: true or false With CSV_ENCODE_BOOLEAN_NUM flag: 1 or 0 |
| Restricted Character String types | Quoted cstring or list notation | Quoted strings.
With CSV_USE_UNICODE_ESCAPE_SEQUENCE flag: "\\u0000" format is used for Unicode characters |
| CHOICE | The selected alternative name is included as 'chosen : <value>' | All alternatives are present, the ones that are not chosen have empty values with extra separators for all their nested components. |
| ENUMERATED | identifier | Default: enumerator's identifier
With CSV_ENCODE_ENUMERATED_NUM flag: enumerator's numeric value |
| GeneralizedTime | "20120808131347+0500" | The same non-quoted value |
| NULL | NULL | null |
| OBJECT IDENTIFIER, RELATIVE-OID |
{arc1(num1) arc2 ... } or encoded format | Dot notation: 1.3.6.1.4.1.1900 |
| OCTET STRINGS | hstring '6B646F726C793031'H |
xmlhstring 6B646F726C793031 |
| Types with ContentsConstraint | bstring | Automatically decoded if the containing PDU is known. |
| REAL | Different representations, including {mantissa, base, exponent} notation | Decimal format |
| SET, SEQUENCE | Values for fields with OPTIONAL/DEFAULT can be absent | Columns for all fields with all their nested components are present. Missing values for optional fields are marked with extra separators. Missing values for fields with DEFAULT have values from the DEFAULT syntax. |
| SET OF, SEQUENCE OF | Component values are included in {val1, val2, ...} | One column is present for only one component. The row for the complete PDU is repeated for each extra component. |
| TIME, DATE, and other time types | "2010-04-15T17:18:18-07:00" | The same quoted value |
| UTCTime | "200808131347Z" | The same non-quoted value |
| Circularly defined types | Values for nested types are printed. | The same value |
| Fields marked with the ASN1.Remove, OSS.NOENCODE, OSS.USERFIELD directive | Ignored | Ignored without extra columns |
Note: Support of Comma-Separated Value encoding rules is a chargeable feature in non-evaluation licenses. Contact Sales to obtain pricing information.
This documentation applies to release 8.0 and later of the OSS® ASN.1 Tools for C++.
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.