Skip to content
Snippets Groups Projects
Commit a6102076 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

OOP: documented more clarifications and limitations, and documented usage of...

OOP: documented more clarifications and limitations, and documented usage of external classes and object references in the API guide (bug 552011)

Change-Id: I650fc3d5e5ca54507a072581eed04f99f3ba1970
Signed-off-by: default avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent a1d027fe
No related branches found
No related tags found
No related merge requests found
......@@ -12,7 +12,7 @@ The functions of Test Ports must be written by the user who knows the interface
A Test Port consists of two parts. One part is generated automatically by the Compiler, and it is put into the generated {cpp} code. The user has nothing to do with this part.
The other part is a {cpp} class, which is written mainly by the user. This class can be found in a separate {cpp} header and source file (their suffixes are `.hh` and `.cc`, respectively). The names of the source files and the {cpp} class are identical to the name of the port type. Please note that the name mapping rules described in <<5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc#mapping-of-names-and-identifiers, Mapping of Names and Identifiers>> also apply to these class and file names.
The other part is a {cpp} class, which is written mainly by the user. This class can be found in a separate {cpp} header and source file (their suffixes are `.hh` and `.cc`, respectively). The names of the source files and the {cpp} class are identical to the name of the port type. Please note that the name mapping rules described in <<6-mapping_ttcn3_data_types_to_c++_constructs.adoc#mapping-of-names-and-identifiers, Mapping of Names and Identifiers>> also apply to these class and file names.
During the translation, when the Compiler encounters a port type definition and the `*–t*` command line switch is used, it checks whether the header and source files of Test Port exist in its working directory. If none of them can be found there, the compiler generates the skeleton header and source files for the corresponding test port automatically. This means, once you have generated (and possibly modified) a skeleton, it will never be overwritten. If you want to re-generate the skeleton, you must rename or remove the existing one.
......@@ -526,13 +526,13 @@ Outgoing operations are `send` (specific to message based ports); `call`, `reply
The Test Port class has an overloaded function called `outgoing_send` for each outgoing message type. This function will be called when a message is sent on the port and it should be routed to the system (that is, SUT) according to the addressing semanticsfootnote:[That is, the port has exactly one mapping and either the port has no connections or the message is explicitly addressed by a `send (…) to system` statement.] of TTCN–3. The messages (implicitly or explicitly) addressed to other test components are handled inside the test executor; the Test Ports have nothing to do with them. The function `outgoing_send` will be also called if the port has neither connections nor mappings, but a message is sent on it.
The only parameter of `outgoing_send` contains a read-only reference to the message in the internal data representation format of the test executor. The access methods for internal data types are described in <<4-encoding_and_decoding.adoc#xml-encoding-xer, XML Encoding (XER)>>. The test port writer should encode and send the message towards SUT. For information on how to use the standard encoding functions like BER, please consult <<3-logger_plug-ins.adoc, Logger Plug-ins>>. Sending a message on a not started port causes a dynamic test case error. In this case outgoing_send will not be called.
The only parameter of `outgoing_send` contains a read-only reference to the message in the internal data representation format of the test executor. The access methods for internal data types are described in <<5-encoding_and_decoding.adoc#xml-encoding-xer, XML Encoding (XER)>>. The test port writer should encode and send the message towards SUT. For information on how to use the standard encoding functions like BER, please consult <<4-logger_plug-ins.adoc, Logger Plug-ins>>. Sending a message on a not started port causes a dynamic test case error. In this case outgoing_send will not be called.
==== Call, Reply and Raise Functions
The procedure based Test Port class has overloaded functions called `outgoing_call`, `outgoing_reply` and `outgoing_raise` for each `call`, `reply` and `raise` operations, respectively. One of these functions will be called when a port-operation is addressing the system (that is, SUT using the to `system` statement).
The only parameter of these functions is an internal representation of the signature parameters (and possibly its return value) or the exceptions it may raise. The signature classes are described in <<5-mapping_ttcn3_data_types_to_c++_constructs.adoc#using-the-signature-classes,Using the Signature Classes>>.
The only parameter of these functions is an internal representation of the signature parameters (and possibly its return value) or the exceptions it may raise. The signature classes are described in <<6-mapping_ttcn3_data_types_to_c++_constructs.adoc#using-the-signature-classes,Using the Signature Classes>>.
=== Incoming Operations
......@@ -626,7 +626,7 @@ incoming_message(const CHARSTRING& incoming_par);
==== Receiving calls, replies and exceptions
Receiving operations on procedure based ports is similar to receiving messages on message based ports. The difference is that there are different overloaded incoming functions for call, reply and raise operations called `incoming_call`, `incoming_reply` and `incoming_exception`, respectively. The event handler (when called) must recognize the type of operation on receiving and call one of these functions accordingly with one of the internal representations of the signature (see <<5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc #additional-non-standard-functions, Additional Non-Standard Functions>>).
Receiving operations on procedure based ports is similar to receiving messages on message based ports. The difference is that there are different overloaded incoming functions for call, reply and raise operations called `incoming_call`, `incoming_reply` and `incoming_exception`, respectively. The event handler (when called) must recognize the type of operation on receiving and call one of these functions accordingly with one of the internal representations of the signature (see <<6-mapping_ttcn3_data_types_to_c++_constructs.adoc #additional-non-standard-functions, Additional Non-Standard Functions>>).
In the examplefootnote:[In the example the signatures were defined in a different TTCN–3 module named MyExample, as a consequence all types defined in that module must be prefixed with the {cpp} namespace name of that module.] the class `MyProcedurePort_BASE` has the following member functions for incoming operations:
[source]
......@@ -925,7 +925,7 @@ The following sections deal with logging and error handling in Test Ports.
Test Ports may record important events in the Test Executor log during sending/receiving or encoding/decoding messages. Such log messages are also good for debugging fresh code.
The Test Port member functions may call the functions of class `TTCN_Logger`. These functions are detailed in <<6-tips_&_troubleshooting.adoc#logging-in-test-ports-or-external-functions, Logging in Test Ports or External Functions>>.
The Test Port member functions may call the functions of class `TTCN_Logger`. These functions are detailed in <<7-tips_&_troubleshooting.adoc#logging-in-test-ports-or-external-functions, Logging in Test Ports or External Functions>>.
If there are many points in the Test Port code that want to log something, it can be a good practice to write a common log function in the Test Port class. We show here an example function, which takes its arguments as the standard C function `printf` and forwards the message to the Test Executor’s logger:
......@@ -987,7 +987,7 @@ This function puts an entry in the executor’s log with severity `TTCN_WARNING`
== Setting timestamps
In order to use the timestamp redirects (`-> timestamp`) described in chapter 5 of the TTCN-3 standard extension `TTCN-3 Performance and Real Time Testing` (ETSI ES 202 782 V1.3.1, <<7-references.adoc#_16, [16]>>) the test port writer needs to add extra code to set the timestamps for the incoming and outgoing port operations of each port with the `realtime` clause.
In order to use the timestamp redirects (`-> timestamp`) described in chapter 5 of the TTCN-3 standard extension `TTCN-3 Performance and Real Time Testing` (ETSI ES 202 782 V1.3.1, <<8-references.adoc#_16, [16]>>) the test port writer needs to add extra code to set the timestamps for the incoming and outgoing port operations of each port with the `realtime` clause.
=== Incoming operations
......
= External Classes
:table-number: 0
:toc:
There is currently no {cpp} skeleton generator for external classes, so any external classes have to be implemented manually.
External class implementation must abide by the following rules:
* The file name, where the external class is declared, must be the name of the external class followed by `.hh`. Please note that the name mapping rules described in <<6-mapping_ttcn3_data_types_to_c++_constructs.adoc#mapping-of-names-and-identifiers, Mapping of Names and Identifiers>> also apply to the class and file name. The implementations of class methods can be in any {cpp} source file that is linked to the executable test suite.
* The new `.hh` file must include the generated header file of the TTCN-3 module containing the external class declaration.
* The include to the new `.hh` file is already in the desired namespace in the generated {cpp} code, so no further namespaces are needed around the external class declaration.
* The external class must inherit the built-in {cpp} class `OBJECT` (`object` in TTCN-3).
* The C++ equivalents of all functions in the TTCN-3 external function declaration must be virtual.
* The class must also have a virtual destructor (even if it is empty).
* For more information about function parameters and return values of class types see <<6-mapping_ttcn3_data_types_to_c++_constructs.adoc#object-references, Object References>>.
== Example
Example.ttcn:
[source]
----
type external class ExternalClass {
public external function f_ext(in integer x) return charstring;
external function f_ext2(inout OtherClass p);
}
----
ExternalClass.hh:
[source]
----
#include "Example.hh"
#ifndef EXTERNALCLASS_HH
#define EXTERNALCLASS_HH
// NOTE: no namespace specification needed, since the 'include' command is
// already in the desired namespace!
class ExternalClass : public OBJECT {
public:
virtual CHARSTRING f__ext(const INTEGER& x);
protected:
virtual void f__ext2(OBJECT_REF<OtherClass>& p);
public:
virtual ~ExternalClass() { }
// additional members and methods
};
#endif
----
ExternalClass.cc:
[source]
----
#include "ExternalClass.hh"
namespace Example {
CHARSTRING ExternalClass::f__ext(const INTEGER& x)
{
// method implementation
}
void ExternalClass::f__ext2(OBJECT_REF<OtherClass>& p)
{
// method implementation
}
}
----
NOTE: If external class methods are implemented in a different {cpp} file, than the mentioned new `.hh` file (such as `ExternalClass.cc` in this case), then they need to be placed in the TTCN-3 module's namespace.
......@@ -558,7 +558,7 @@ The following user-defined types can be encoded in XML:
* record of and set of types, if the type of the element can be encoded.
The encoder and the decoder are working with XML data encoded in UTF-8 (described in link:https://tools.ietf.org/html/rfc3629[UTF-8, a transformation format of ISO 10646]), stored in an object of type `TTCN_buffer`. Although the contents of this object can be retrieved (using the overloads of the get_string function) as an instance of `OCTETSTRING`, `CHARSTRING` or `UNIVERSAL_CHARSTRING`, it is recommended to use only the `OCTETSTRING` representation. `CHARSTRING` is not recommended, because UTF-8 is an 8-bit encoding so the buffer may contain bytes with values over 127, which are not valid characters for a TTCN-3 `charstring` (which is implemented by `CHARSTRING`, see <<5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc#Charstring, Charstring>>). `UNIVERSAL_CHARSTRING` must not be used because its internal representation is not UTF-8.
The encoder and the decoder are working with XML data encoded in UTF-8 (described in link:https://tools.ietf.org/html/rfc3629[UTF-8, a transformation format of ISO 10646]), stored in an object of type `TTCN_buffer`. Although the contents of this object can be retrieved (using the overloads of the get_string function) as an instance of `OCTETSTRING`, `CHARSTRING` or `UNIVERSAL_CHARSTRING`, it is recommended to use only the `OCTETSTRING` representation. `CHARSTRING` is not recommended, because UTF-8 is an 8-bit encoding so the buffer may contain bytes with values over 127, which are not valid characters for a TTCN-3 `charstring` (which is implemented by `CHARSTRING`, see <<6-mapping_ttcn3_data_types_to_c+\+_constructs.adoc#Charstring, Charstring>>). `UNIVERSAL_CHARSTRING` must not be used because its internal representation is not UTF-8.
[[error-situations-2]]
=== Error Situations
......@@ -726,7 +726,7 @@ The rules also apply to the following ASN.1 types (if imported to a TTCN-3 modul
The compiler will produce code capable of JSON encoding/decoding for compound types if they have at least one JSON variant attribute or the `encode "JSON"` attribute (and, for compound types, all fields and elements of compound types also have a JSON variant attribute or the `encode "JSON"` attribute).
The encoder and the decoder work with JSON data encoded in UTF-8 (described in link:https://tools.ietf.org/html/rfc3629[UTF-8, a transformation format of ISO 10646]), stored in an object of type `TTCN_buffer`. Although the contents of this object can be retrieved (using the overloads of the `get_string` function) as an instance of `OCTETSTRING`, `CHARSTRING` or `UNIVERSAL_CHARSTRING`, it is recommended to use only the `OCTETSTRING` representation. `CHARSTRING` is not recommended, because UTF-8 is an 8-bit encoding so the buffer may contain bytes with values over 127, which are not valid characters for a TTCN-3 `charstring` (which is implemented by `CHARSTRING`, see <<5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc#Charstring, Charstring>>). `UNIVERSAL_CHARSTRING` must not be used because its internal representation is not UTF-8.
The encoder and the decoder work with JSON data encoded in UTF-8 (described in link:https://tools.ietf.org/html/rfc3629[UTF-8, a transformation format of ISO 10646]), stored in an object of type `TTCN_buffer`. Although the contents of this object can be retrieved (using the overloads of the `get_string` function) as an instance of `OCTETSTRING`, `CHARSTRING` or `UNIVERSAL_CHARSTRING`, it is recommended to use only the `OCTETSTRING` representation. `CHARSTRING` is not recommended, because UTF-8 is an 8-bit encoding so the buffer may contain bytes with values over 127, which are not valid characters for a TTCN-3 `charstring` (which is implemented by `CHARSTRING`, see <<6-mapping_ttcn3_data_types_to_c+\+_constructs.adoc#Charstring, Charstring>>). `UNIVERSAL_CHARSTRING` must not be used because its internal representation is not UTF-8.
[[error-situations-3]]
=== Error Situations
......
......@@ -814,7 +814,7 @@ The four components of the quadruple (that is, group, plane, row and cell) are s
In case of single-octet characters, which can be also given in TTCN–3 charstring notation (between quotation marks), the fields `uc_group`, `uc_plane`, `uc_row` are set to zero. If tuple notation was used for an ASN.1 string value fields `uc_row` and `uc_cell` carry the tuple and the others are set to zero.
Except when performing encoding or decoding, the run-time environment does not check whether the quadruples used in the following API represent valid character positions according to <<7-references.adoc#_8,[8]>>. Moreover, if ASN.1 multi-octet character string values are used, it is not verified whether the elements of such strings are permitted characters of the corresponding string type.
Except when performing encoding or decoding, the run-time environment does not check whether the quadruples used in the following API represent valid character positions according to <<8-references.adoc#_8,[8]>>. Moreover, if ASN.1 multi-octet character string values are used, it is not verified whether the elements of such strings are permitted characters of the corresponding string type.
The {cpp} equivalent of TTCN–3 type `universal charstring` is implemented in class `UNIVERSAL_CHARSTRING`. The characters of the string are stored in an array of structure `universal_char`. The array returned by the casting operator is not terminated with a special character, thus, the length of the string must be always considered when doing operations with the array. The length of the string, which can be obtained by using member function `lengthof()`, is measured in characters (quadruples) and not bytes.
......@@ -1951,3 +1951,44 @@ even if the exception type is defined in the same module as the signature.
For example, if exception type `My_Record` is defined in module `My_Module`
the respective field access functions will be named as `My\__Module_My__Record_field` and
the associated enum value will be `MyProc_exception::ALT_My\__Module_My__Record`.
[[object-references]]
== Object references
All function parameters, return values and variables of class type must use the `OBJECT_REF` wrapper class, with the class type as its template parameter (e.g. `MyClass` in TTCN-3 translates to `OBJECT_REF<MyClass>` in {cpp}). This class contains a pointer to the class object itself, and handles its reference counting and deallocation.
Accessing members and methods through `OBJECT_REF` is done through the operator `->` (as if it were a pointer in {cpp}). Methods of `OBJECT_REF` are accessed through the operator `.` (see below).
.Public methods of the template class `OBJECT_REF<T>`, where `T` is a class type
[cols=",,",]
|==================================================
2+^.^|*Member functions* |*Notes*
.5+^.^|_Constructors_
|`OBJECT_REF()` |Initializes to `null` reference.
|`OBJECT_REF(null_type)` |Initializes to `null` reference.
|`OBJECT_REF(T*)` |Initializes to a new object, which needs to be allocated with the {cpp} operator `new`.
|`OBJECT_REF(const OBJECT_REF<T>&)` |Copy constructor.
|`template <typename T2>
OBJECT_REF(OBJECT_REF<T2>&)` |Copy constructor for a reference of a different class type, referring to an object of type `T` or a subclass of `T`.
^.^|_Destructor_
|`~OBJECT_REF()` |
.3+^.^|_Assignment operators_
|`OBJECT_REF& operator=(null_type)` |Assigns the `null` reference.
|`OBJECT_REF& operator=(const OBJECT_REF<T>&)` |Assigns a reference of `T`.
|`template <typename T2>
OBJECT_REF& operator=(OBJECT_REF<T2>&)` |Assigns a reference of a different class type, referring to an object of type `T` or a subclass of `T`.
.4+^.^|_Comparison operators_
|`boolean operator==(null_type) const` | Returns TRUE if the reference is `null`.
|`boolean operator!=(null_type) const` | Returns FALSE if the reference is `null`.
|`boolean operator==(const OBJECT_REF<T>&) const` | Returns TRUE if both this and the parameter refer to the same object.
|`boolean operator!=(const OBJECT_REF<T>&) const` | Returns FALSE if both this and the parameter refer to the same object.
.3+^.^|_Access operators_
|`T* operator*()` |Returns a pointer to the actual object.
|`T* operator->()` |Accesses the object's members and methods.
|`const T* operator->() const` |Accesses the object's constant members and methods.
.4+^.^|_Other methods_
| `void log() const` |Puts the object (or `null`) into the log.
| `boolean is_bound() const` |Returns TRUE if the reference is not `null`.
| `boolean is_value() const` |Returns TRUE if the reference is not `null`.
| `boolean is_present() const` |Returns TRUE if the reference is not `null`.
|==================================================
......@@ -59,7 +59,7 @@ The compiler will translate those external function definitions to {cpp} functio
[...]
----
Both pre-defined and user-defined TTCN–3 data types can be used as parameters and/or return types of the {cpp} functions. The detailed description of the equivalent {cpp} classes as well as the name mapping rules are described in chapter <<4-encoding_and_decoding.adoc#xml-encoding-xer,XML Encoding (XER)>>.
Both pre-defined and user-defined TTCN–3 data types can be used as parameters and/or return types of the {cpp} functions. The detailed description of the equivalent {cpp} classes as well as the name mapping rules are described in chapter <<5-encoding_and_decoding.adoc#xml-encoding-xer,XML Encoding (XER)>>.
Using templates as formal parameters in external functions is possible, but not recommended because the API of the classes realizing templates is not documented and subject to change without notice.
......
......@@ -37,22 +37,24 @@ The contents of this document are subject to revision without notice due to cont
ifdef::env-github,backend-html5[]
* link:1-introduction.adoc[Introduction]
* link:2-test_ports.adoc[Test Ports]
* link:3-logger_plug-ins.adoc[Logger Plug-ins]
* link:4-encoding_and_decoding.adoc[Encoding and Decoding]
* link:5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc[Mapping TTCN–3 Data Types to {cpp} Constructs]
* link:6-tips_and_troubleshooting.adoc[Tips & Troubleshooting]
* link:7-references.adoc[References]
* link:8-abbreviations.adoc[Abbreviations]
* link:3-external_classes.adoc[External Classes]
* link:4-logger_plug-ins.adoc[Logger Plug-ins]
* link:5-encoding_and_decoding.adoc[Encoding and Decoding]
* link:6-mapping_ttcn3_data_types_to_c+\+_constructs.adoc[Mapping TTCN–3 Data Types to {cpp} Constructs]
* link:7-tips_and_troubleshooting.adoc[Tips & Troubleshooting]
* link:8-references.adoc[References]
* link:9-abbreviations.adoc[Abbreviations]
endif::[]
ifndef::env-github,backend-html5[]
include::1-introduction.adoc[leveloffset=+1]
include::2-test_ports.adoc[leveloffset=+1]
include::3-logger_plug-ins.adoc[leveloffset=+1]
include::4-encoding_and_decoding.adoc[leveloffset=+1]
include::5-mapping_ttcn3_data_types_to_c++_constructs.adoc[leveloffset=+1]
include::6-tips_and_troubleshooting.adoc[leveloffset=+1]
include::7-references.adoc[leveloffset=+1]
include::8-abbreviations.adoc[leveloffset=+1]
include::3-external_classes.adoc[leveloffset=+1]
include::4-logger_plug-ins.adoc[leveloffset=+1]
include::5-encoding_and_decoding.adoc[leveloffset=+1]
include::6-mapping_ttcn3_data_types_to_c++_constructs.adoc[leveloffset=+1]
include::7-tips_and_troubleshooting.adoc[leveloffset=+1]
include::8-references.adoc[leveloffset=+1]
include::9-abbreviations.adoc[leveloffset=+1]
endif::[]
......@@ -8976,6 +8976,9 @@ TITAN supports the object-oriented programming features described in chapter 5 o
* Class members of `port` and `port array` types are not allowed.
* Class member `templates` cannot have parameters.
* Exceptions are not currently supported.
* The `select class` statement is not currently supported.
* The `of`-operator (Dynamic Class Discrimination) is not currently supported.
* The casting of classes (`=>` operator) is not currently supported.
* Unhandled dynamic test case errors inside the destructor of a class cause the program to terminate (due to C++ limitations).
* The `with` attributes of class members and methods are currently ignored.
* Members of `timer` and `timer array` types cannot be initialized in the constructor, and the default constructor doesn't add a formal parameter for the initialization of these members.
......@@ -9039,5 +9042,15 @@ log(my_object1 == my_object3); // false
* The reference `this` can be used inside a class method, constructor or destructor to access members and methods of the class. The stand-alone `this` refers to the object itself.
* The reference `super` can be used inside a class method, constructor or destructor to access methods of the superclass.
* The predefined functions `isbound`, `isvalue` and `ispresent`, with an object reference as parameter, return true, if the object reference is not `null`.
* Function parameters of class type are passed by reference, which means:
** an `in` parameter of class type can be changed to refer to a different object inside the function, but it will keep referring to the initial object after the function call;
any changes made to the initally referred object will remain active after the function call;
variables, function parameters, the `null` reference and the result of a class `create` operation are valid `in` actual parameters;
** an `inout` parameter of class type retains all changes to the object reference and the referred object after the function call;
only variables and function parameters are valid `inout` actual parameters;
** an `out` parameter of class type is set to `null` at the beginning of the function (since objects don't have an `unbound` state), and retains all changes made to the object reference after the function call;
only variables and function parameters are valid `out` actual parameters.
* External classes and external methods in classes cannot be abstract.
* A definition in the subclass can only have the same name as a definition in one of the superclasses, if both are methods (incl. external or abstract), and both have the same prototype (i.e. identical return type, identical formal parameter names, types and direction).
* Internal classes can define external methods, even if they are not derived from an external class.
* There are no restrictions to visibility of members or methods (i.e. members can be public and overriding methods can have any visibility, regardless of the overriden method's visibility).
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment