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