1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 ///////////////////////////////////////////////////////////////////////////////
11 #include <sys/types.h>
15 #include "Basetype.hh"
16 #include "Template.hh"
17 #include "Optional.hh"
23 class CHARSTRING_ELEMENT;
24 class UNIVERSAL_CHARSTRING;
25 class UNIVERSAL_CHARSTRING_ELEMENT;
29 /** Runtime class for character strings.
31 * Memory is reserved for the terminating null character
32 * (not counted in the length).
34 * This class implements the following string types:
36 * - TTCN-3 \c charstring
37 * - ASN.1 restricted character strings:
39 * - \c PrintableString
44 * - \c GeneralizedTime
47 class CHARSTRING : public Base_Type {
49 friend class CHARSTRING_ELEMENT;
50 friend class UNIVERSAL_CHARSTRING;
51 friend class UNIVERSAL_CHARSTRING_ELEMENT;
52 friend class TTCN_Buffer;
53 friend class CHARSTRING_template;
55 friend boolean operator==(const char* string_value,
56 const CHARSTRING& other_value);
57 friend CHARSTRING operator+(const char* string_value,
58 const CHARSTRING& other_value);
59 friend CHARSTRING operator+(const char* string_value,
60 const CHARSTRING_ELEMENT& other_value);
62 friend CHARSTRING bit2str(const BITSTRING& value);
63 friend CHARSTRING hex2str(const HEXSTRING& value);
64 friend CHARSTRING oct2str(const OCTETSTRING& value);
65 friend CHARSTRING unichar2char(const UNIVERSAL_CHARSTRING& value);
66 friend CHARSTRING replace(const CHARSTRING& value, int index, int len,
67 const CHARSTRING& repl);
68 friend UNIVERSAL_CHARSTRING operator+(const universal_char& uchar_value,
69 const UNIVERSAL_CHARSTRING_ELEMENT& other_value);
70 friend UNIVERSAL_CHARSTRING operator+(const universal_char& uchar_value,
71 const UNIVERSAL_CHARSTRING& other_value);
72 friend boolean operator==(const universal_char& uchar_value,
73 const UNIVERSAL_CHARSTRING& other_value);
74 friend boolean operator==(const char *string_value,
75 const UNIVERSAL_CHARSTRING_ELEMENT& other_value);
76 friend UNIVERSAL_CHARSTRING operator+(const char *string_value,
77 const UNIVERSAL_CHARSTRING& other_value);
78 friend UNIVERSAL_CHARSTRING operator+(const char *string_value,
79 const UNIVERSAL_CHARSTRING_ELEMENT& other_value);
81 struct charstring_struct;
82 charstring_struct *val_ptr;
84 void init_struct(int n_chars);
86 CHARSTRING(int n_chars);
88 /** An extended version of set_param(), which also accepts string patterns if
89 * the second parameter is set (needed by CHARSTRING_template to concatenate
91 * @return TRUE, if the module parameter was a string pattern, otherwise FALSE */
92 boolean set_param_internal(Module_Param& param, boolean allow_pattern);
95 /** Construct an unbound CHARSTRING object */
97 /** Construct a CHARSTRING of length 1 */
98 CHARSTRING(char other_value);
99 /** Construct a CHARSTRING from the given C string.
100 * @param chars_ptr may be NULL, resulting in an empty CHARSTRING */
101 CHARSTRING(const char* chars_ptr);
102 /** Construct a CHARSTRING of a given length.
104 * CHARSTRING(0,NULL) is the most efficient way to a bound, empty string.
106 * @param n_chars number of characters
107 * @param chars_ptr pointer to string (does not need to be 0-terminated)
108 * @pre at least \p n_chars are readable from \p chars_ptr */
109 CHARSTRING(int n_chars, const char* chars_ptr);
110 /** Copy constructor */
111 CHARSTRING(const CHARSTRING& other_value);
112 /** Construct a CHARSTRING of length one */
113 CHARSTRING(const CHARSTRING_ELEMENT& other_value);
115 /** Destructor. Simply calls clean_up() */
119 CHARSTRING& operator=(const char* other_value);
120 CHARSTRING& operator=(const CHARSTRING& other_value);
121 CHARSTRING& operator=(const CHARSTRING_ELEMENT& other_value);
122 CHARSTRING& operator=(const UNIVERSAL_CHARSTRING& other_value);
124 boolean operator==(const char* other_value) const;
125 boolean operator==(const CHARSTRING& other_value) const;
126 boolean operator==(const CHARSTRING_ELEMENT& other_value) const;
127 boolean operator==(const UNIVERSAL_CHARSTRING& other_value) const;
128 boolean operator==(const UNIVERSAL_CHARSTRING_ELEMENT& other_value) const;
130 inline boolean operator!=(const char* other_value) const
131 { return !(*this == other_value); }
132 inline boolean operator!=(const CHARSTRING& other_value) const
133 { return !(*this == other_value); }
134 inline boolean operator!=(const CHARSTRING_ELEMENT& other_value) const
135 { return !(*this == other_value); }
137 CHARSTRING operator+(const char* other_value) const;
138 CHARSTRING operator+(const CHARSTRING& other_value) const;
139 CHARSTRING operator+(const CHARSTRING_ELEMENT& other_value) const;
140 UNIVERSAL_CHARSTRING operator+(const UNIVERSAL_CHARSTRING& other_value) const;
141 UNIVERSAL_CHARSTRING operator+
142 (const UNIVERSAL_CHARSTRING_ELEMENT& other_value) const;
144 CHARSTRING& operator+=(char other_value);
145 CHARSTRING& operator+=(const char *other_value);
146 CHARSTRING& operator+=(const CHARSTRING& other_value);
147 CHARSTRING& operator+=(const CHARSTRING_ELEMENT& other_value);
149 CHARSTRING operator<<=(int rotate_count) const;
150 CHARSTRING operator<<=(const INTEGER& rotate_count) const;
151 CHARSTRING operator>>=(int rotate_count) const;
152 CHARSTRING operator>>=(const INTEGER& rotate_count) const;
154 CHARSTRING_ELEMENT operator[](int index_value);
155 CHARSTRING_ELEMENT operator[](const INTEGER& index_value);
156 const CHARSTRING_ELEMENT operator[](int index_value) const;
157 const CHARSTRING_ELEMENT operator[](const INTEGER& index_value) const;
159 operator const char*() const;
161 inline boolean is_bound() const { return val_ptr != NULL; }
162 inline boolean is_value() const { return val_ptr != NULL; }
163 inline void must_bound(const char *err_msg) const
164 { if (val_ptr == NULL) TTCN_error("%s", err_msg); }
166 int lengthof() const;
170 #ifdef TITAN_RUNTIME_2
171 boolean is_equal(const Base_Type* other_value) const { return *this == *(static_cast<const CHARSTRING*>(other_value)); }
172 void set_value(const Base_Type* other_value) { *this = *(static_cast<const CHARSTRING*>(other_value)); }
173 Base_Type* clone() const { return new CHARSTRING(*this); }
174 const TTCN_Typedescriptor_t* get_descriptor() const { return &CHARSTRING_descr_; }
176 inline boolean is_present() const { return is_bound(); }
179 /** Initializes this object with a module parameter value or concatenates a module
180 * parameter value to the end of this string.
181 * @note UFT-8 strings will be decoded. If the decoding results in multi-octet
182 * characters an error will be thrown. */
183 void set_param(Module_Param& param);
184 Module_Param* get_param(Module_Param_Name& param_name) const;
186 void encode_text(Text_Buf& text_buf) const;
187 void decode_text(Text_Buf& text_buf);
189 void encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
190 TTCN_EncDec::coding_t p_coding, ...) const;
192 void decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
193 TTCN_EncDec::coding_t p_coding, ...);
195 ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
196 unsigned p_coding) const;
198 boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
199 const ASN_BER_TLV_t& p_tlv, unsigned L_form);
201 /** Encodes the value of the variable according to the
202 * TTCN_Typedescriptor_t. It must be public because called by
203 * another types during encoding. Returns the length of encoded
205 int RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;
206 /** Decodes the value of the variable according to the
207 * TTCN_Typedescriptor_t. It must be public because called by
208 * another types during encoding. Returns the number of decoded
210 int RAW_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, int, raw_order_t,
211 boolean no_err=FALSE, int sel_field=-1, boolean first_call=TRUE);
212 int TEXT_encode(const TTCN_Typedescriptor_t&,
214 int TEXT_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, Limit_Token_List&,
215 boolean no_err=FALSE, boolean first_call=TRUE);
216 int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, embed_values_enc_struct_t*) const;
217 int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, embed_values_dec_struct_t*);
219 /** Returns the charstring in the format a string would appear in C or TTCN-3 code.
220 * Inserts double quotation marks to the beginning and end of the string and
221 * doubles the backlsashes in escaped characters.
222 * Used for JSON encoding.
224 * Example: "He said\nhis name was \"Al\"." -> "\"He said\\nhis name was \\\"Al\\\".\""
225 * @note The returned character buffer needs to be freed after use. */
226 char* to_JSON_string() const;
228 /** Initializes the charstring with a JSON string value.
229 * The double quotation marks from the beginning and end of the JSON string are
230 * removed and double-escaped characters are changed to simple-escaped ones.
231 * JSON characters stored as \u + 4 hex digits are converted to the characters
233 * Returns false if any non-charstring characters were found, otherwise true.
234 * Used for JSON decoding.
236 * Example: "\"He said\\nhis name was \\\"Al\\\".\"" -> "He said\nhis name was \"Al\"."
237 * Example2: "\u0061" -> "a"
239 * @param check_quotes turn the checking of double quotes (mentioned above) on or off */
240 boolean from_JSON_string(const char* p_value, size_t p_value_len, boolean check_quotes);
242 /** Encodes accordingly to the JSON encoding rules.
243 * Returns the length of the encoded data.
244 * @note Since JSON has its own set of escaped characters, the ones in the
245 * charstring need to be double-escaped. */
246 int JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;
248 /** Decodes accordingly to the JSON encoding rules.
249 * Returns the length of the decoded data. */
250 int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);
252 #ifdef TITAN_RUNTIME_2
253 virtual int encode_raw(TTCN_Buffer& p_buf) const;
254 /** Adds this charstring to the end of a JSON buffer as raw data.
255 * Used during the negative testing of the JSON encoder.
256 * @return The number of bytes added. */
257 int JSON_encode_negtest_raw(JSON_Tokenizer&) const;
261 class CHARSTRING_ELEMENT {
267 CHARSTRING_ELEMENT(boolean par_bound_flag, CHARSTRING& par_str_val,
270 CHARSTRING_ELEMENT& operator=(const char* other_value);
271 CHARSTRING_ELEMENT& operator=(const CHARSTRING& other_value);
272 CHARSTRING_ELEMENT& operator=(const CHARSTRING_ELEMENT& other_value);
274 boolean operator==(const char *other_value) const;
275 boolean operator==(const CHARSTRING& other_value) const;
276 boolean operator==(const CHARSTRING_ELEMENT& other_value) const;
277 boolean operator==(const UNIVERSAL_CHARSTRING& other_value) const;
278 boolean operator==(const UNIVERSAL_CHARSTRING_ELEMENT& other_value) const;
280 inline boolean operator!=(const char *other_value) const
281 { return !(*this == other_value); }
282 inline boolean operator!=(const CHARSTRING& other_value) const
283 { return !(*this == other_value); }
284 inline boolean operator!=(const CHARSTRING_ELEMENT& other_value) const
285 { return !(*this == other_value); }
287 CHARSTRING operator+(const char *other_value) const;
288 CHARSTRING operator+(const CHARSTRING& other_value) const;
289 CHARSTRING operator+(const CHARSTRING_ELEMENT& other_value) const;
290 UNIVERSAL_CHARSTRING operator+(const UNIVERSAL_CHARSTRING& other_value) const;
291 UNIVERSAL_CHARSTRING operator+
292 (const UNIVERSAL_CHARSTRING_ELEMENT& other_value) const;
294 inline boolean is_bound() const { return bound_flag; }
295 inline boolean is_present() const { return bound_flag; }
296 inline boolean is_value() const { return bound_flag; }
297 inline void must_bound(const char *err_msg) const
298 { if (!bound_flag) TTCN_error("%s", err_msg); }
300 char get_char() const;
305 extern boolean operator==(const char* string_value,
306 const CHARSTRING& other_value);
307 extern boolean operator==(const char* string_value,
308 const CHARSTRING_ELEMENT& other_value);
310 inline boolean operator!=(const char* string_value,
311 const CHARSTRING& other_value)
313 return !(string_value == other_value);
316 inline boolean operator!=(const char* string_value,
317 const CHARSTRING_ELEMENT& other_value)
319 return !(string_value == other_value);
322 extern CHARSTRING operator+(const char* string_value,
323 const CHARSTRING& other_value);
324 extern CHARSTRING operator+(const char* string_value,
325 const CHARSTRING_ELEMENT& other_value);
327 extern CHARSTRING operator<<=(const char *string_value,
328 const INTEGER& rotate_count);
329 extern CHARSTRING operator>>=(const char *string_value,
330 const INTEGER& rotate_count);
332 // charstring template class
334 class CHARSTRING_template : public Restricted_Length_Template {
336 friend class UNIVERSAL_CHARSTRING_template;
339 CHARSTRING single_value;
342 unsigned int n_values;
343 CHARSTRING_template *list_value;
346 boolean min_is_set, max_is_set;
347 char min_value, max_value;
351 regex_t posix_regexp;
355 void copy_template(const CHARSTRING_template& other_value);
356 static void log_pattern(int n_chars, const char *chars_ptr);
359 CHARSTRING_template();
360 /** Constructor for any/omit/any-or-omit
361 * @param other_value must be ANY_VALUE, OMIT_VALUE or ANY_OR_OMIT
363 CHARSTRING_template(template_sel other_value);
364 /** Construct from a string
365 * @post template_selection is SPECIFIC_VALUE
368 CHARSTRING_template(const CHARSTRING& other_value);
369 /** Construct from a one-character string (result of CHARSTRING::op[])
370 * @post template_selection is SPECIFIC_VALUE
373 CHARSTRING_template(const CHARSTRING_ELEMENT& other_value);
374 /** Construct from an optional string
375 * @post template_selection is SPECIFIC_VALUE or OMIT_VALUE
378 CHARSTRING_template(const OPTIONAL<CHARSTRING>& other_value);
379 /** Constructor for STRING_PATTERN
380 * @param p_sel must be STRING_PATTERN or else Dynamic Testcase Error
381 * @param p_str pattern string
383 CHARSTRING_template(template_sel p_sel, const CHARSTRING& p_str);
385 CHARSTRING_template(const CHARSTRING_template& other_value);
387 ~CHARSTRING_template();
390 CHARSTRING_template& operator=(template_sel other_value);
391 CHARSTRING_template& operator=(const CHARSTRING& other_value);
392 CHARSTRING_template& operator=(const CHARSTRING_ELEMENT& other_value);
393 CHARSTRING_template& operator=(const OPTIONAL<CHARSTRING>& other_value);
394 CHARSTRING_template& operator=(const CHARSTRING_template& other_value);
396 CHARSTRING_ELEMENT operator[](int index_value);
397 CHARSTRING_ELEMENT operator[](const INTEGER& index_value);
398 const CHARSTRING_ELEMENT operator[](int index_value) const;
399 const CHARSTRING_ELEMENT operator[](const INTEGER& index_value) const;
401 boolean match(const CHARSTRING& other_value, boolean legacy = FALSE) const;
402 const CHARSTRING& valueof() const;
404 int lengthof() const;
406 void set_type(template_sel template_type, unsigned int list_length = 0);
407 CHARSTRING_template& list_item(unsigned int list_index);
409 void set_min(const CHARSTRING& min_value);
410 void set_max(const CHARSTRING& max_value);
413 void log_match(const CHARSTRING& match_value, boolean legacy = FALSE) const;
415 void set_param(Module_Param& param);
416 Module_Param* get_param(Module_Param_Name& param_name) const;
418 void encode_text(Text_Buf& text_buf) const;
419 void decode_text(Text_Buf& text_buf);
421 boolean is_present(boolean legacy = FALSE) const;
422 boolean match_omit(boolean legacy = FALSE) const;
423 #ifdef TITAN_RUNTIME_2
424 void valueofv(Base_Type* value) const { *(static_cast<CHARSTRING*>(value)) = valueof(); }
425 void set_value(template_sel other_value) { *this = other_value; }
426 void copy_value(const Base_Type* other_value) { *this = *(static_cast<const CHARSTRING*>(other_value)); }
427 Base_Template* clone() const { return new CHARSTRING_template(*this); }
428 const TTCN_Typedescriptor_t* get_descriptor() const { return &CHARSTRING_descr_; }
429 boolean matchv(const Base_Type* other_value, boolean legacy) const { return match(*(static_cast<const CHARSTRING*>(other_value)), legacy); }
430 void log_matchv(const Base_Type* match_value, boolean legacy) const { log_match(*(static_cast<const CHARSTRING*>(match_value)), legacy); }
432 void check_restriction(template_res t_res, const char* t_name=NULL, boolean legacy = FALSE) const;
435 /** Returns the single_value member
436 * @pre template_selection is SPECIFIC_VALUE or STRING_PATTERN */
437 const CHARSTRING& get_single_value() const;
440 typedef CHARSTRING NumericString;
441 typedef CHARSTRING PrintableString;
442 typedef CHARSTRING IA5String;
443 typedef CHARSTRING VisibleString;
444 typedef VisibleString ISO646String;
446 typedef CHARSTRING_template NumericString_template;
447 typedef CHARSTRING_template PrintableString_template;
448 typedef CHARSTRING_template IA5String_template;
449 typedef CHARSTRING_template VisibleString_template;
450 typedef VisibleString_template ISO646String_template;
452 typedef VisibleString ASN_GeneralizedTime;
453 typedef VisibleString ASN_UTCTime;
455 typedef VisibleString_template ASN_GeneralizedTime_template;
456 typedef VisibleString_template ASN_UTCTime_template;
458 // Only for backward compatibility
459 typedef CHARSTRING CHAR;
460 typedef CHARSTRING_template CHAR_template;
462 // TTCN_TYPE is a class that represents a ttcn-3 value or template
463 template<typename TTCN_TYPE>
464 CHARSTRING ttcn_to_string(const TTCN_TYPE& ttcn_data) {
465 Logger_Format_Scope logger_format(TTCN_Logger::LF_TTCN);
466 TTCN_Logger::begin_event_log2str();
468 return TTCN_Logger::end_event_log2str();
471 template<typename TTCN_TYPE>
472 void string_to_ttcn(const CHARSTRING& ttcn_string, TTCN_TYPE& ttcn_value) {
473 Module_Param* parsed_mp = process_config_string2ttcn((const char*)ttcn_string, ttcn_value.is_component());
475 Ttcn_String_Parsing ttcn_string_parsing;
476 ttcn_value.set_param(*parsed_mp);