Contents
The OSS ASN.1/C++ API consists of control, coding, representation, memory management, and utility classes. Both coding and representation classes are generated from the input ASN.1 specification. Representation classes are used to store actual PDU data in decoded form. Coding classes act as containers for representation classes and can encode and decode. Separating encoding and decoding from the representation results in generated code that is much smaller. Control classes are used to hold the encoded data and to control the encoding or decoding process. Use memory management classes to create non-standard memory allocation and deallocation strategies for representation classes. Also, the ASN.1/C++ Runtime can use these classes for temporary storage. Utility classes are intermediate classes that offer the most convenient value handling for some representation classes.
The API does not use the C++ Standard Template Library and does not depend on it in any way. This makes it possible to use the same OSS ASN.1 Tools for C++ port for different STL implementations.
The OSS ASN.1 Tools for C++ uses exceptions to signal errors, by default.
If your C++ compiler does not provide adequate exception support or exceptions must be avoided, set the legacy "no-exception" error handling function or provide your own error-handling function by calling
void asn1_set_error_handling(void (*func)(int), int complete = FALSE);
Now the ASN.1/C++ runtime will call the specified function whenever an error that cannot be returned as a function result occurs. The error handling function parameter is a non-zero error code. Use the optional second parameter to call the error handling function for every error or only when the error cannot return an error code.
Use the following function to get a textual description of the numeric return code from any ASN.1/C++ API method or constructor:
char *asn1_describe_error_code(int retcode);
The function returns a pointer to the string that contains a description of the given return code, as specified by the retcode parameter. If the return code is invalid or unknown, NULL is returned.
In modern C++, the preferred way to perform error handling is to use exceptions. Use "full-exception" mode to avoid checking ASN.1/C++ Runtime function results and completely rely on exceptions for error handling. However, if your C++ compiler is not good at exception support you cannot use this mode. The ASN.1/C++ Runtime uses the following default exception class:
class ASN1RuntimeException { private: int code; public: ASN1RuntimeException(int asn1_code); ASN1RuntimeException(const ASN1RuntimeException & that); int get_code() const; char* describe_error() const; };
Alternatively, you can define a special ASN.1 exception class, use any other exception class, or simply throw error codes as integers, as shown in the following example:
class ASN1Error: public exception { public: ASN1Error(int code); . . . };
Next, the error-handling function, which throws an ASN.1 exception class object, is implemented:
void throw_error(int code) { throw ASN1Error(code); }
Finally, the ASN.1/C++ Runtime is notified of the new error-handling function:
asn1_set_error_handling(throw_error, TRUE);
TRUE, the second parameter, specifies that the error handling function is called for every error.
To maintain compatibility with user code written for the ASN.1/C++ Runtime versions 6.0 and older, set the legacy error handling mode before initializing any ASN.1/C++ objects:
asn1_set_error_handling(asn1_legacy_error_handler);
The pre-defined asn1_legacy_error_handler() function saves the last error code in a static variable. In this mode, an ASN.1/C++ Runtime function usually returns its completion status as the result, though this is not always possible. For example, C++ constructors do not return results, so errors occurring in constructors must be signaled some other way. In legacy error handling mode, read the last error code using the following function:
int asn1_get_last_error();
So, if you are unsure that a constructor will succeed, check it in the following manner:
SomeType a(...); if (error_code = asn1_get_last_error()) // an error occurred
To have your application continue after an error has been handled, reset the last error code to 0 using the following function:
void asn1_clean_error();
This error handling method is not thread-safe. Since all threads share the last_error_code variable, one thread could disrupt the operations of another. If your application is multithreaded, we recommend using the default "full-exception" error handling or implementing your own error handling function, probably using C++ exceptions.
There is another potential, platform-dependent problem using the legacy error handling mode with some C++ compilers. Memory allocation for representation types is performed using the C++ compilers' operator new functions. These functions call the error handling function when there is insufficient memory. If the error handling function does not throw exceptions, the operator new function returns NULL. Some C++ compilers (e.g., Sun CC, Microsoft VC++) can handle this as a memory allocation failure and avoid calling the constructor, while others (e.g., g++) call the constructor with this pointer equal to NULL, leading to a segmentation fault. So, if you are using g++, your application will not be robust if the legacy error handling mode is used and a memory deficit occurs. Use the "full-exception" or "compatibility" mode instead.
This mode is similar to the "full-exception" mode but the asn1_set_error_handling function is called with the second argument set to FALSE:
asn1_set_error_handling(throw_error, FALSE);
Or, since FALSE is the default value of the second argument, you can simply omit it:
asn1_set_error_handling(throw_error);
In this mode, the ASN.1/C++ Runtime functions return error codes as results whenever possible, as in the legacy "no-exception" mode. The error handling function is called only when the error code cannot be returned as the function's result, such as in constructors.
You can implement your own error handling function without using C++ exceptions, but this only makes sense in rare situations. For example, your C++ compiler does not support exceptions, or does but consumes excessive resources. Your application is multithreaded, so the legacy error handling mode is unsatisfactory. This is when implementing a custom error handling function without using C++ exceptions is called for.
Several different approaches are possible:
When custom error handing is implemented, the default error handling no longer works. Do not bother calling asn1_get_last_error: it will always return the last value stored in the static error variable when asn1_set_error_handling was called, which is usually 0. Error handling is done exclusively by the custom error handling function. To check the error code, implement a custom error checking function that retrieves the error code from where the error handling function stored it.
The code generated by the ASN.1/C++ Compiler could rely on exception support for the target C++ compiler. If your C++ compiler supports exceptions but you plan to disable this using the appropriate command line option, be sure to define the EXCEPTIONS_SUPPORTED preprocessor symbol as 0 when compiling the generated code. For example, specify -DEXCEPTIONS_SUPPORTED=0 on the C++ compiler command line.
The topics listed below are grouped by class category. Get detailed information about a category, class, or topic by clicking on its name.
This documentation applies to release 7.3 and later of the OSS® ASN.1 Tools for C++.
Copyright © 2024 OSS Nokalva, Inc. All rights reserved.
No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means electronic, mechanical, photocopying, recording or otherwise, without the prior permission of OSS Nokalva, Inc.
Every distributed copy of the OSS® ASN.1 Tools for C++ is associated with a specific license and related unique license number. That license determines, among other things, what functions of the OSS ASN.1 Tools for C++ are available to you.