Commit | Line | Data |
---|---|---|
970ed795 | 1 | /////////////////////////////////////////////////////////////////////////////// |
3abe9331 | 2 | // Copyright (c) 2000-2015 Ericsson Telecom AB |
970ed795 EL |
3 | // All rights reserved. This program and the accompanying materials |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | #ifndef TTCNSTUFF_H_ | |
9 | #define TTCNSTUFF_H_ | |
10 | ||
11 | #include "../Setting.hh" | |
12 | #include "../Type.hh" // for Common::Common::Type::MessageEncodingType_t | |
13 | #include "AST_ttcn3.hh" // For Def_Function_Base::prototype_t | |
14 | #include "port.h" | |
15 | #include "../vector.hh" | |
16 | ||
17 | namespace Ttcn { | |
18 | ||
19 | class Reference; | |
20 | ||
21 | /** | |
22 | * Class to represent an error behavior setting in the codec API of the | |
23 | * run-time environment. The setting contains a pair of strings: | |
24 | * the error type identifier and the way of error handling. | |
25 | */ | |
26 | class ErrorBehaviorSetting : public Common::Node, public Common::Location { | |
27 | private: | |
28 | string error_type, error_handling; | |
29 | public: | |
30 | ErrorBehaviorSetting(const string& p_error_type, | |
31 | const string& p_error_handling) | |
32 | : Common::Node(), Common::Location(), error_type(p_error_type), | |
33 | error_handling(p_error_handling) { } | |
34 | virtual ErrorBehaviorSetting *clone() const; | |
35 | const string& get_error_type() const { return error_type; } | |
36 | void set_error_type(const string& p_error_type) | |
37 | { error_type = p_error_type; } | |
38 | const string& get_error_handling() const { return error_handling; } | |
39 | void set_error_handling(const string& p_error_handling) | |
40 | { error_handling = p_error_handling; } | |
41 | virtual void dump(unsigned level) const; | |
42 | }; | |
43 | ||
44 | /** | |
45 | * Class to represent a list of error behavior settings in the codec API | |
46 | * of the run-time environment. | |
47 | */ | |
48 | class ErrorBehaviorList : public Common::Node, public Common::Location { | |
49 | private: | |
50 | vector<ErrorBehaviorSetting> ebs_v; | |
51 | map<string, ErrorBehaviorSetting> ebs_m; | |
52 | ErrorBehaviorSetting *ebs_all; | |
53 | bool checked; | |
54 | /** Copy constructor not implemented */ | |
55 | ErrorBehaviorList(const ErrorBehaviorList& p); | |
56 | /** Assignment disabled */ | |
57 | ErrorBehaviorList& operator=(const ErrorBehaviorList& p); | |
58 | public: | |
59 | ErrorBehaviorList() : Common::Node(), Common::Location(), ebs_all(0), checked(false) { } | |
60 | virtual ~ErrorBehaviorList(); | |
61 | virtual ErrorBehaviorList *clone() const; | |
62 | virtual void set_fullname(const string& p_fullname); | |
63 | void add_ebs(ErrorBehaviorSetting *p_ebs); | |
64 | void steal_ebs(ErrorBehaviorList *p_eblist); | |
65 | size_t get_nof_ebs() const { return ebs_v.size(); } | |
66 | ErrorBehaviorSetting *get_ebs_byIndex(size_t n) const { return ebs_v[n]; } | |
67 | bool has_setting(const string& p_error_type); | |
68 | string get_handling(const string& p_error_type); | |
69 | void chk(); | |
70 | char *generate_code(char *str); | |
71 | virtual void dump(unsigned level) const; | |
72 | }; | |
73 | ||
74 | /** Printing type class for JSON encoder functions */ | |
75 | class PrintingType : public Common::Node, public Common::Location { | |
76 | public: | |
77 | /** Printing types */ | |
78 | enum printing_t { | |
79 | /** No printing has been set */ | |
80 | PT_NONE, | |
81 | /** Printing without any white spaces to make the JSON code as short as possible */ | |
82 | PT_COMPACT, | |
83 | /** Printing with extra white spaces to make the JSON code easier to read */ | |
84 | PT_PRETTY | |
85 | }; | |
86 | ||
87 | PrintingType() : Common::Node(), Common::Location(), printing(PT_NONE) { } | |
88 | virtual ~PrintingType() {}; | |
89 | virtual PrintingType *clone() const; | |
90 | void set_printing(printing_t p_pt) { printing = p_pt; } | |
91 | printing_t get_printing() const { return printing; } | |
92 | char *generate_code(char *str); | |
93 | ||
94 | private: | |
95 | printing_t printing; | |
96 | ||
97 | /** Copy constructor not implemented */ | |
98 | PrintingType(const PrintingType& p); | |
99 | /** Assignment disabled */ | |
100 | PrintingType& operator=(const PrintingType& p); | |
101 | }; | |
102 | ||
103 | /** A single target type for type mapping */ | |
104 | class TypeMappingTarget : public Common::Node, public Common::Location { | |
105 | public: | |
106 | enum TypeMappingType_t { | |
107 | TM_SIMPLE, /**< simple mapping (source == target) */ | |
108 | TM_DISCARD, /**< the message is discarded (target type is NULL) */ | |
109 | TM_FUNCTION, /**< mapping using a [external] function */ | |
110 | TM_ENCODE, /**< mapping using a built-in encoder */ | |
111 | TM_DECODE /**< mapping using a built-in decoder */ | |
112 | }; | |
113 | private: | |
114 | Common::Type *target_type; // owned | |
115 | TypeMappingType_t mapping_type; | |
116 | union { | |
117 | struct { | |
118 | Ttcn::Reference *function_ref; | |
119 | Ttcn::Def_Function_Base *function_ptr; | |
120 | } func; | |
121 | struct { | |
122 | Common::Type::MessageEncodingType_t coding_type; // BER,RAW,... | |
123 | string *coding_options; | |
124 | ErrorBehaviorList *eb_list; | |
125 | } encdec; | |
126 | } u; | |
127 | bool checked; | |
128 | /** Copy constructor not implemented */ | |
129 | TypeMappingTarget(const TypeMappingTarget& p); | |
130 | /** Assignment disabled */ | |
131 | TypeMappingTarget& operator=(const TypeMappingTarget& p); | |
132 | public: | |
133 | /** Constructor for TM_SIMPLE and TM_DISCARD. */ | |
134 | TypeMappingTarget(Common::Type *p_target_type, TypeMappingType_t p_mapping_type); | |
135 | /** Constructor for TM_FUNCTION. */ | |
136 | TypeMappingTarget(Common::Type *p_target_type, TypeMappingType_t p_mapping_type, | |
137 | Ttcn::Reference *p_function_ref); | |
138 | /** Constructor for TM_ENCODE and TM_DECODE. */ | |
139 | TypeMappingTarget(Common::Type *p_target_type, TypeMappingType_t p_mapping_type, | |
140 | Common::Type::MessageEncodingType_t p_coding_type, string *p_coding_options, | |
141 | ErrorBehaviorList *p_eb_list); | |
142 | virtual ~TypeMappingTarget(); | |
143 | virtual TypeMappingTarget *clone() const; | |
144 | virtual void set_fullname(const string& p_fullname); | |
145 | virtual void set_my_scope(Common::Scope *p_scope); | |
146 | TypeMappingType_t get_mapping_type() const { return mapping_type; } | |
147 | /** Returns the string representation of \a mapping_type */ | |
148 | const char *get_mapping_name() const; | |
149 | Common::Type *get_target_type() const { return target_type; } | |
150 | /** Applicable if \a mapping_type is TM_FUNCTION. */ | |
151 | Ttcn::Def_Function_Base *get_function() const; | |
152 | /** Applicable if \a mapping_type is TM_ENCODE or TM_DECODE. */ | |
153 | Common::Type::MessageEncodingType_t get_coding_type() const; | |
154 | /** Applicable if \a mapping_type is TM_ENCODE or TM_DECODE. */ | |
155 | bool has_coding_options() const; | |
156 | /** Applicable if \a mapping_type is TM_ENCODE or TM_DECODE and | |
157 | * \a has_coding_options() returned true. */ | |
158 | const string& get_coding_options() const; | |
159 | /** Applicable if \a mapping_type is TM_ENCODE or TM_DECODE. */ | |
160 | ErrorBehaviorList *get_eb_list() const; | |
161 | private: | |
162 | /** Check that the source_type is identical with the target_type of | |
163 | * this simple mapping. */ | |
164 | void chk_simple(Common::Type *source_type); | |
165 | /** Check function mapping. | |
166 | * The function must have "prototype()", the function's input parameter | |
167 | * must match the source_type and its return type must match the target_type | |
168 | * of this mapping. */ | |
169 | void chk_function(Common::Type *source_type); | |
170 | /** Check "encode()" mapping. */ | |
171 | void chk_encode(Common::Type *source_type); | |
172 | /** Check "decode()" mapping. */ | |
173 | void chk_decode(Common::Type *source_type); | |
174 | public: | |
175 | void chk(Common::Type *source_type); | |
176 | /** Fills the appropriate data structure \a target for code generation. */ | |
177 | bool fill_type_mapping_target(port_msg_type_mapping_target *target, | |
178 | Common::Type *source_type, Common::Scope *p_scope, stringpool& pool); | |
179 | virtual void dump(unsigned level) const; | |
180 | }; | |
181 | ||
182 | /** A list of mapping targets */ | |
183 | class TypeMappingTargets : public Common::Node { | |
184 | private: | |
185 | vector<TypeMappingTarget> targets_v; | |
186 | /** Copy constructor not implemented */ | |
187 | TypeMappingTargets(const TypeMappingTargets& p); | |
188 | /** Assignment disabled */ | |
189 | TypeMappingTargets& operator=(const TypeMappingTargets& p); | |
190 | public: | |
191 | TypeMappingTargets() : Common::Node() { } | |
192 | virtual ~TypeMappingTargets(); | |
193 | virtual TypeMappingTargets *clone() const; | |
194 | virtual void set_fullname(const string& p_fullname); | |
195 | virtual void set_my_scope(Common::Scope *p_scope); | |
196 | void add_target(TypeMappingTarget *p_target); | |
197 | size_t get_nof_targets() const { return targets_v.size(); } | |
198 | TypeMappingTarget *get_target_byIndex(size_t n) const | |
199 | { return targets_v[n]; } | |
200 | virtual void dump(unsigned level) const; | |
201 | }; | |
202 | ||
203 | /** A mapping. | |
204 | * One source type, multiple targets: | |
205 | * @code | |
206 | * in(octetstring -> PDU1 : function(f), | |
207 | * PDU2 : decode(RAW), | |
208 | * - : discard | |
209 | * ) | |
210 | * @endcode | |
211 | */ | |
212 | class TypeMapping : public Common::Node, public Common::Location { | |
213 | private: | |
214 | Common::Type *source_type; | |
215 | TypeMappingTargets *targets; | |
216 | /** Copy constructor not implemented */ | |
217 | TypeMapping(const TypeMapping& p); | |
218 | /** Assignment disabled */ | |
219 | TypeMapping& operator=(const TypeMapping& p); | |
220 | public: | |
221 | TypeMapping(Common::Type *p_source_type, TypeMappingTargets *p_targets); | |
222 | virtual ~TypeMapping(); | |
223 | virtual TypeMapping *clone() const; | |
224 | virtual void set_fullname(const string& p_fullname); | |
225 | virtual void set_my_scope(Common::Scope *p_scope); | |
226 | Common::Type *get_source_type() const { return source_type; } | |
227 | size_t get_nof_targets() const { return targets->get_nof_targets(); } | |
228 | TypeMappingTarget *get_target_byIndex(size_t n) const | |
229 | { return targets->get_target_byIndex(n); } | |
230 | void chk(); | |
231 | virtual void dump(unsigned level) const; | |
232 | }; | |
233 | ||
234 | class TypeMappings : public Common::Node, public Common::Location { | |
235 | private: | |
236 | vector<TypeMapping> mappings_v; | |
237 | map<string, TypeMapping> mappings_m; | |
238 | bool checked; | |
239 | /** Copy constructor not implemented */ | |
240 | TypeMappings(const TypeMappings& p); | |
241 | /** Assignment disabled */ | |
242 | TypeMappings& operator=(const TypeMappings& p); | |
243 | public: | |
244 | TypeMappings() : Common::Node(), Common::Location(), checked(false) { } | |
245 | virtual ~TypeMappings(); | |
246 | virtual TypeMappings *clone() const; | |
247 | virtual void set_fullname(const string& p_fullname); | |
248 | virtual void set_my_scope(Common::Scope *p_scope); | |
249 | void add_mapping(TypeMapping *p_mapping); | |
250 | void steal_mappings(TypeMappings *p_mappings); | |
251 | size_t get_nof_mappings() const { return mappings_v.size(); } | |
252 | TypeMapping *get_mapping_byIndex(size_t n) const { return mappings_v[n]; } | |
253 | bool has_mapping_for_type(Common::Type *p_type) const; | |
254 | TypeMapping *get_mapping_byType(Common::Type *p_type) const; | |
255 | void chk(); | |
256 | virtual void dump(unsigned level) const; | |
257 | }; | |
258 | ||
259 | /** | |
260 | * Type list, used in port types | |
261 | */ | |
262 | class Types : public Common::Node, public Common::Location { | |
263 | private: | |
264 | vector<Common::Type> types; | |
265 | /** Copy constructor not implemented */ | |
266 | Types(const Types& p); | |
267 | /** Assignment disabled */ | |
268 | Types& operator=(const Types& p); | |
269 | public: | |
270 | Types() : Common::Node(), Common::Location() { } | |
271 | virtual ~Types(); | |
272 | virtual Types *clone() const; | |
273 | ||
274 | /** Add a new type to the list. | |
275 | * It is now owned by the list. */ | |
276 | void add_type(Common::Type *p_type); | |
277 | /** Moves (appends) all types of \a p_tl into this. */ | |
278 | void steal_types(Types *p_tl); | |
279 | size_t get_nof_types() const { return types.size(); } | |
280 | /** Return a type based on its index. */ | |
281 | Common::Type *get_type_byIndex(size_t n) const { return types[n]; } | |
282 | /** Remove a type from the list and return it. | |
283 | * The old value is replaced with a NULL pointer. */ | |
284 | Common::Type *extract_type_byIndex(size_t n); | |
285 | ||
286 | virtual void set_fullname(const string& p_fullname); | |
287 | virtual void set_my_scope(Common::Scope *p_scope); | |
288 | virtual void dump(unsigned level) const; | |
289 | }; | |
290 | ||
291 | /** | |
292 | * Unique set of types. It does not own its members. The types are identified | |
293 | * using the string returned by get_typename(). | |
294 | */ | |
295 | class TypeSet : public Common::Node { | |
296 | /** Copy constructor not implemented */ | |
297 | TypeSet(const TypeSet& p); | |
298 | /** Assignment not implemented */ | |
299 | TypeSet& operator=(const TypeSet& p); | |
300 | private: | |
301 | vector<Common::Type> types_v; | |
302 | map<string, Common::Type> types_m; | |
303 | public: | |
304 | TypeSet() : Common::Node() { } | |
305 | virtual ~TypeSet(); | |
306 | virtual TypeSet *clone() const; | |
307 | ||
308 | /** Adds type \a p_type to the set. */ | |
309 | void add_type(Common::Type *p_type); | |
310 | /** Returns the number of types in the set. */ | |
311 | size_t get_nof_types() const { return types_v.size(); } | |
312 | /** Returns the \a n-th element of the set. */ | |
313 | Common::Type *get_type_byIndex(size_t n) const { return types_v[n]; } | |
314 | /** Returns whether type \a p_type is a member of the set. */ | |
315 | bool has_type(Common::Type *p_type) const; | |
316 | /** Returns the number of types in the set that are compatible with | |
317 | * \a p_type. */ | |
318 | size_t get_nof_compatible_types(Common::Type *p_type) const; | |
319 | /** Returns the index of type \a p_type in the set. It is assumed that | |
320 | * \a p_type is a member of the set, otherwise FATAL_ERROR occurs. */ | |
321 | size_t get_index_byType(Common::Type *p_type) const; | |
322 | /** Returns whether the set contains a type with typename \a p_name. */ | |
323 | bool has_type_withName(const string& p_name) const | |
324 | { return types_m.has_key(p_name); } | |
325 | /** Returns the type from the set with typename \a p_name. */ | |
326 | Common::Type *get_type_byName(const string& p_name) const | |
327 | { return types_m[p_name]; } | |
328 | ||
329 | virtual void dump(unsigned level) const; | |
330 | }; | |
331 | ||
332 | /** Class to hold a parsed PortDefAttribs. | |
333 | * This includes the operation mode and the input/output types. */ | |
334 | class PortTypeBody : public Common::Node, public Common::Location { | |
335 | public: | |
336 | /** | |
337 | * Enumeration to represent TTCN-3 port operation modes. | |
338 | */ | |
339 | enum PortOperationMode_t { | |
340 | PO_MESSAGE, | |
341 | PO_PROCEDURE, | |
342 | PO_MIXED | |
343 | }; | |
344 | /** | |
345 | * Enumeration to represent the test port API variants. | |
346 | */ | |
347 | enum TestPortAPI_t { | |
348 | TP_REGULAR, /**< regular test port API */ | |
349 | TP_INTERNAL, /**< no test port (only connections are allowed) */ | |
350 | TP_ADDRESS /**< usage of the address type is supported */ | |
351 | }; | |
352 | /** | |
353 | * Enumeration to represent the the properties of the port type. | |
354 | */ | |
355 | enum PortType_t { | |
356 | PT_REGULAR, /**< regular port type */ | |
357 | PT_PROVIDER, /**< the port type provides the external interface for other | |
358 | * port types */ | |
359 | PT_USER /**< the port type uses another port type as external interface */ | |
360 | }; | |
361 | private: | |
362 | Common::Type *my_type; // the Type that owns this object | |
363 | PortOperationMode_t operation_mode; // message|procedure|mixed | |
364 | Types *in_list, *out_list, *inout_list; | |
365 | bool in_all, out_all, inout_all; // whether "(in|out|inout) all" was used | |
366 | bool checked; | |
367 | /* Types and signatures that can be sent and received. | |
368 | * These are initially empty; filled by PortTypeBody::chk_list based on | |
369 | * in_list, out_list, inout_list. | |
370 | * Signature types are added to _sigs, "normal" types to _msgs. | |
371 | */ | |
372 | TypeSet *in_msgs, *out_msgs, *in_sigs, *out_sigs; | |
373 | TestPortAPI_t testport_type; // regular|internal|address | |
374 | PortType_t port_type; // regular|provider|user | |
375 | Ttcn::Reference *provider_ref; ///< reference to provider port, for PT_USER | |
376 | Common::Type *provider_type; ///< the type that provider_ref refers to | |
377 | TypeMappings *in_mappings, *out_mappings; ///< mappings for PT_USER | |
378 | /** Copy constructor not implemented */ | |
379 | PortTypeBody(const PortTypeBody& p); | |
380 | /** Assignment disabled */ | |
381 | PortTypeBody& operator=(const PortTypeBody& p); | |
382 | public: | |
383 | PortTypeBody(PortOperationMode_t p_operation_mode, | |
384 | Types *p_in_list, Types *p_out_list, Types *p_inout_list, | |
385 | bool p_in_all, bool p_out_all, bool p_inout_all); | |
386 | ~PortTypeBody(); | |
387 | virtual PortTypeBody *clone() const; | |
388 | virtual void set_fullname(const string& p_fullname); | |
389 | virtual void set_my_scope(Common::Scope *p_scope); | |
390 | void set_my_type(Common::Type *p_type); | |
391 | PortOperationMode_t get_operation_mode() const { return operation_mode; } | |
392 | TypeSet *get_in_msgs() const; | |
393 | TypeSet *get_out_msgs() const; | |
394 | TypeSet *get_in_sigs() const; | |
395 | TypeSet *get_out_sigs() const; | |
396 | bool has_queue() const; | |
397 | bool getreply_allowed() const; | |
398 | bool catch_allowed() const; | |
399 | bool is_internal() const; | |
400 | /** Returns the address type that can be used in communication operations | |
401 | * on this port type. NULL is returned if addressing inside SUT is not | |
402 | * supported or the address type does not exist. */ | |
403 | Common::Type *get_address_type(); | |
404 | TestPortAPI_t get_testport_type() const { return testport_type; } | |
405 | void set_testport_type(TestPortAPI_t p_testport_type) | |
406 | { testport_type = p_testport_type; } | |
407 | PortType_t get_type() const { return port_type; } | |
408 | void add_provider_attribute(); | |
409 | void add_user_attribute(Ttcn::Reference *p_provider_ref, | |
410 | TypeMappings *p_in_mappings, TypeMappings *p_out_mappings); | |
411 | Common::Type *get_provider_type() const; | |
412 | private: | |
413 | void chk_list(const Types *list, bool is_in, bool is_out); | |
414 | void chk_user_attribute(); | |
415 | public: | |
416 | void chk(); | |
417 | void chk_attributes(Ttcn::WithAttribPath *w_attrib_path); | |
418 | /** Returns whether the outgoing messages and signatures of \a this are | |
419 | * on the incoming lists of \a p_other. */ | |
420 | bool is_connectable(PortTypeBody *p_other) const; | |
421 | /** Reports the error messages about the outgoing types of \a this that | |
422 | * are not handled by the incoming lists of \a p_other. | |
423 | * Applicable only if \a is_connectable() returned false. */ | |
424 | void report_connection_errors(PortTypeBody *p_other) const; | |
425 | /** Returns whether \a this as the type of a test component port can be | |
426 | * mapped to a system port with type \a p_other. */ | |
427 | bool is_mappable(PortTypeBody *p_other) const; | |
428 | /** Reports all errors that prevent mapping of \a this as the type of a | |
429 | * test component port to system port \a p_other. | |
430 | * Applicable only if \a is_mappable() returned false. */ | |
431 | void report_mapping_errors(PortTypeBody *p_other) const; | |
432 | void generate_code(output_struct *target); | |
433 | virtual void dump(unsigned level) const; | |
434 | }; | |
435 | ||
436 | /** Class to represent an "extension" attribute. | |
437 | * | |
438 | */ | |
439 | class ExtensionAttribute : public Location { | |
440 | public: | |
441 | enum extension_t { NONE, PROTOTYPE, ENCODE, DECODE, PORT_API, // 0-4 | |
442 | PORT_TYPE_USER, PORT_TYPE_PROVIDER, ERRORBEHAVIOR, ANYTYPELIST, // 5-8 | |
443 | ENCDECVALUE, VERSION, VERSION_TEMPLATE, REQUIRES, REQ_TITAN, // 9-13 | |
444 | TRANSPARENT, PRINTING // 14-15 | |
445 | }; | |
446 | ||
447 | /// Constructor for the PROTOTYPE type (convert, fast, backtrack, sliding) | |
448 | ExtensionAttribute(Def_Function_Base::prototype_t p) | |
449 | : Location(), type_(PROTOTYPE), value_() | |
450 | { | |
451 | value_.proto_ = p; | |
452 | } | |
453 | ||
454 | /// Constructor for the ENCODE/DECODE type | |
455 | ExtensionAttribute(extension_t t, Type::MessageEncodingType_t met, | |
456 | string *enc_opt) | |
457 | : Location(), type_(t), value_() | |
458 | { | |
459 | if (type_ != ENCODE && type_ != DECODE) | |
460 | FATAL_ERROR("ExtensionAttribute::ExtensionAttribute()"); | |
461 | value_.encdec_.mess_ = met; | |
462 | value_.encdec_.s_ = enc_opt; // may be NULL | |
463 | } | |
464 | ||
465 | /// Constructor for the ERRORBEHAVIOR type | |
466 | ExtensionAttribute(ErrorBehaviorList *ebl) | |
467 | : Location(), type_(ERRORBEHAVIOR), value_() | |
468 | { | |
469 | if (ebl == NULL) FATAL_ERROR("ExtensionAttribute::ExtensionAttribute()"); | |
470 | value_.ebl_ = ebl; | |
471 | } | |
472 | ||
473 | /// Constructor for the PRINTING type | |
474 | ExtensionAttribute(PrintingType *pt) | |
475 | : Location(), type_(PRINTING), value_() | |
476 | { | |
477 | if (NULL == pt) { | |
478 | FATAL_ERROR("ExtensionAttribute::ExtensionAttribute()"); | |
479 | } | |
480 | value_.pt_ = pt; | |
481 | } | |
482 | ||
483 | /// Constructor for the PORT_API type (internal or address) | |
484 | ExtensionAttribute(PortTypeBody::TestPortAPI_t api) | |
485 | : Location(), type_(PORT_API), value_() | |
486 | { | |
487 | value_.api_ = api; | |
488 | } | |
489 | ||
490 | /// Constructor for the PORT_TYPE_PROVIDER and TRANSPARENT type | |
491 | ExtensionAttribute(extension_t type) | |
492 | : Location(), type_(type), value_() | |
493 | { | |
494 | switch (type) { | |
495 | case PORT_TYPE_PROVIDER: | |
496 | case TRANSPARENT: | |
497 | break; | |
498 | default: | |
499 | FATAL_ERROR("ExtensionAttribute::ExtensionAttribute()"); | |
500 | } | |
501 | } | |
502 | ||
503 | /// Constructor for the USER type | |
504 | ExtensionAttribute(Reference *ref, TypeMappings *in, TypeMappings *out) | |
505 | : Location(), type_(PORT_TYPE_USER), value_() | |
506 | { | |
507 | if (in == NULL && out == NULL) // one may be null but not both | |
508 | FATAL_ERROR("ExtensionAttribute::ExtensionAttribute()"); | |
509 | value_.user_.ref_ = ref; | |
510 | value_.user_.inmaps_ = in; | |
511 | value_.user_.outmaps_ = out; | |
512 | } | |
513 | ||
514 | /// Constructor for the ANYTYPELIST type | |
515 | ExtensionAttribute(Types *t) | |
516 | : Location(), type_(ANYTYPELIST), value_() | |
517 | { | |
518 | if (t == NULL) FATAL_ERROR("ExtensionAttribute::ExtensionAttribute()"); | |
519 | value_.anytypes_ = t; | |
520 | } | |
521 | ||
522 | /** Constructor for the ENCDECVALUE type | |
523 | * | |
524 | * @param in "in" type mappings | |
525 | * @param out "out" type mappings | |
526 | * @note at most one out of \a in and \a out may be NULL | |
527 | */ | |
528 | ExtensionAttribute(TypeMappings *in, TypeMappings *out) | |
529 | : Location(), type_(ENCDECVALUE), value_() | |
530 | { | |
531 | if (in == NULL && out == NULL) | |
532 | FATAL_ERROR("ExtensionAttribute::ExtensionAttribute"); | |
533 | value_.encdecvalue_.inmaps_ = in; | |
534 | value_.encdecvalue_.outmaps_ = out; | |
535 | } | |
536 | ||
537 | /** Constructor for the VERSION type | |
538 | * | |
539 | * @param ver contains the unparsed version | |
540 | * (a string according to the template "RnXnn") | |
541 | * | |
542 | * Parses \p ver. If parsing is successful, the ExtensionAttribute | |
543 | * becomes responsible for \p ver, otherwise the caller has to free it. | |
544 | */ | |
545 | ExtensionAttribute(const char* ABCClass, int type_number, int sequence, | |
546 | int suffix, Identifier *ver); | |
547 | ||
548 | /** Constructor for the REQUIRES type | |
549 | * | |
550 | * @param mod contains the module name | |
551 | * @param ver contains the unparsed version | |
552 | * (a string according to the template "RnXnn") | |
553 | * | |
554 | * Parses \p ver. If successful, ExtensionAttribute becomes responsible | |
555 | * for both (stores \p mod and deletes \p ver). | |
556 | * If unsuccessful, freeing the identifiers remains the caller's duty. | |
557 | */ | |
558 | ExtensionAttribute(Identifier *mod, const char* ABCClass, int type_number, | |
559 | int sequence, int suffix, Identifier *ver); | |
560 | ||
561 | /** Constructor for the REQ_TITAN type or the VERSION_TEMPLATE type | |
562 | * | |
563 | * @param et either REQ_TITAN or VERSION_TEMPLATE | |
564 | * @param ver contains the unparsed version | |
565 | * (a string according to the template "RnXnn" for REQ_TITAN | |
566 | * or exactly "RnXnn" - the template itself - for VERSION_TEMPLATE) | |
567 | * | |
568 | * Parses \p ver. If parsing is successful, the ExtensionAttribute | |
569 | * becomes responsible for \p ver, otherwise the caller has to free it. | |
570 | */ | |
571 | ExtensionAttribute(const char* ABCClass, int type_number, int sequence, | |
572 | int suffix, Identifier* ver, extension_t et); | |
573 | ||
574 | ~ExtensionAttribute(); | |
575 | ||
576 | /// Return the type of the attribute | |
577 | extension_t get_type() const { return type_; } | |
578 | ||
579 | /** @name Accessors | |
580 | * @{ | |
581 | * All these functions act as extractors: resource ownership is passed | |
582 | * to the caller, and type is set to NONE. Therefore only one of these | |
583 | * functions can be called during object's life, and only once! | |
584 | */ | |
585 | ||
586 | /// Return the data for the anytype | |
587 | /// @pre type_ is ANYTYPELIST, or else FATAL_ERROR | |
588 | /// @post type_ is NONE | |
589 | Types *get_types(); | |
590 | ||
591 | /// Return the data for the prototype (convert, fast, backtrack, sliding) | |
592 | /// @pre type_ is PROTOTYPE, or else FATAL_ERROR | |
593 | /// @post type_ is NONE | |
594 | Ttcn::Def_Function_Base::prototype_t get_proto(); | |
595 | ||
596 | /// Return the data for the encode/decode attribute | |
597 | /// @pre type_ is ENCODE or DECODE, or else FATAL_ERROR | |
598 | /// @post type_ is NONE | |
599 | void get_encdec_parameters(Type::MessageEncodingType_t &p_encoding_type, | |
600 | string *&p_encoding_options); | |
601 | ||
602 | /// Return the error behavior list | |
603 | /// @pre type_ is ERRORBEHAVIOR, or else FATAL_ERROR | |
604 | /// @post type_ is NONE | |
605 | ErrorBehaviorList *get_eb_list(); | |
606 | ||
607 | /// Return the printing type | |
608 | /// @pre type_ is PRINTING, or else FATAL_ERROR | |
609 | /// @post type_ is NONE | |
610 | PrintingType *get_printing(); | |
611 | ||
612 | /// Return the data for (internal or address) | |
613 | /// @pre type_ is PORT_API, or else FATAL_ERROR | |
614 | /// @post type_ is NONE | |
615 | PortTypeBody::TestPortAPI_t get_api(); | |
616 | ||
617 | /// Return the data for the "user" attribute | |
618 | /// @pre type_ is USER, or else FATAL_ERROR | |
619 | /// @post type_ is NONE | |
620 | void get_user(Reference *&ref, TypeMappings *&in, TypeMappings *&out); | |
621 | ||
622 | /// Returns the in and out mappings | |
623 | /// @pre type_ is ENCDECVALUE | |
624 | void get_encdecvalue_mappings(TypeMappings *&in, TypeMappings *&out); | |
625 | ||
626 | /** Return version information | |
627 | * | |
628 | * @pre type_ is REQUIRES, REQ_TITAN, VERSION or VERSION_TEMPLATE | |
629 | * | |
630 | * @param[out] product_number a string like "CRL 113 200" | |
631 | * @param[out] suffix the /3 | |
632 | * @param[out] rel release | |
633 | * @param[out] patch patch version | |
634 | * @param[out] bld build number | |
635 | * @return pointer to the identifier of the module; the caller must not free | |
636 | */ | |
637 | Common::Identifier *get_id(char*& product_number, unsigned int& suffix, | |
638 | unsigned int& rel, unsigned int& patch, unsigned int& bld, char*& extra); | |
639 | /// @} | |
640 | private: | |
641 | /// Attribute type. | |
642 | extension_t type_; | |
643 | /** Internal data. | |
644 | * All pointers are owned by the object and deleted in the destructor. | |
645 | */ | |
646 | union { | |
647 | Ttcn::Def_Function_Base::prototype_t proto_; | |
648 | struct { | |
649 | Common::Type::MessageEncodingType_t mess_; | |
650 | string *s_; | |
651 | } encdec_; | |
652 | ErrorBehaviorList *ebl_; | |
653 | PortTypeBody::TestPortAPI_t api_; | |
654 | struct { | |
655 | Reference *ref_; | |
656 | TypeMappings *inmaps_; | |
657 | TypeMappings *outmaps_; | |
658 | } user_; | |
659 | struct { | |
660 | TypeMappings *inmaps_; | |
661 | TypeMappings *outmaps_; | |
662 | } encdecvalue_; | |
663 | Types *anytypes_; | |
664 | struct { | |
665 | Common::Identifier *module_; | |
666 | char* productNumber_; ///< "CRL 113 200" | |
667 | unsigned int suffix_; ///< The "/3" | |
668 | unsigned int release_;///< release | |
669 | unsigned int patch_; ///< patch | |
670 | unsigned int build_; ///< build number | |
671 | char* extra_; ///< extra junk at the end, for titansim | |
672 | } version_; | |
673 | PrintingType *pt_; | |
674 | } value_; | |
675 | ||
676 | void check_product_number(const char* ABCClass, int type_number, int sequence); | |
677 | void parse_version(Identifier *ver); | |
678 | }; | |
679 | ||
680 | /** Container for ExtensionAttribute. | |
681 | * Private inheritance means is-implemented-in-terms-of. */ | |
682 | class ExtensionAttributes : private vector<ExtensionAttribute> { | |
683 | public: | |
684 | ExtensionAttributes() : vector<ExtensionAttribute>() | |
685 | {} | |
686 | ~ExtensionAttributes(); | |
687 | void add(ExtensionAttribute *a); | |
688 | ||
689 | ExtensionAttribute &get(size_t idx) const | |
690 | { | |
691 | return *vector<ExtensionAttribute>::operator[](idx); | |
692 | } | |
693 | ||
694 | /** Take over the elements of another container. | |
695 | * | |
696 | * @param other source container, will be emptied. | |
697 | */ | |
698 | void import(ExtensionAttributes *other); | |
699 | ||
700 | /// Return the number of elements | |
701 | size_t size() const { return vector<ExtensionAttribute>::size(); } | |
702 | }; | |
703 | ||
704 | } | |
705 | ||
706 | #endif /* TTCNSTUFF_H_ */ |