Bitstring.hh 14.9 KB
Newer Older
Elemer Lelik's avatar
Elemer Lelik committed
1
/******************************************************************************
Adam Knapp's avatar
Adam Knapp committed
2
 * Copyright (c) 2000-2021 Ericsson Telecom AB
Elemer Lelik's avatar
Elemer Lelik committed
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v2.0
Elemer Lelik's avatar
Elemer Lelik committed
5
 * which accompanies this distribution, and is available at
6
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
Elemer Lelik's avatar
Elemer Lelik committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * Contributors:
 *   Balasko, Jeno
 *   Baranyi, Botond
 *   Beres, Szabolcs
 *   Delic, Adam
 *   Forstner, Matyas
 *   Horvath, Gabriella
 *   Kovacs, Ferenc
 *   Raduly, Csaba
 *   Szabados, Kristof
 *   Szabo, Bence Janos
 *   Szabo, Janos Zoltan – initial implementation
 *   Szalai, Gabor
 *   Tatarka, Gabor
 *
 ******************************************************************************/
Elemer Lelik's avatar
Elemer Lelik committed
24
25
26
27
28
29
30
31
#ifndef BITSTRING_HH
#define BITSTRING_HH

#include "Types.h"
#include "Basetype.hh"
#include "Template.hh"
#include "RAW.hh"
#include "BER.hh"
32
#include "Error.hh"
33
#ifdef TITAN_RUNTIME_2
34
#include "Vector.hh"
35
#endif
Elemer Lelik's avatar
Elemer Lelik committed
36
37
38
39
40
41
42
43
44

class INTEGER;
class HEXSTRING;
class OCTETSTRING;
class CHARSTRING;
class BITSTRING_ELEMENT;

class Module_Param;

45
46
47
template<typename T>
class OPTIONAL;

Elemer Lelik's avatar
Elemer Lelik committed
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/** bitstring value class.
 * Refcounted copy-on-write implementation */
class BITSTRING : public Base_Type {

  friend class BITSTRING_ELEMENT;
  friend class BITSTRING_template;

  friend BITSTRING int2bit(const INTEGER& value, int length);
  friend BITSTRING hex2bit(const HEXSTRING& value);
  friend BITSTRING oct2bit(const OCTETSTRING& value);
  friend BITSTRING str2bit(const CHARSTRING& value);
  friend BITSTRING substr(const BITSTRING& value, int index, int returncount);
  friend BITSTRING replace(const BITSTRING& value, int index, int len,
		                   const BITSTRING& repl);

  struct bitstring_struct;
  bitstring_struct *val_ptr;

  /** Allocate memory if needed.
   * @param n_bits the number of bits needed.
   * @pre   n_bits  >= 0
   * @post  val_ptr != 0
   * If n_bits > 0, allocates n_bits/8 bytes of memory
   * */
  void init_struct(int n_bits);
  /// Get the bit at the given index.
  boolean get_bit(int bit_index) const;
  /// Assign \p new_value to the bit at the given index
  void set_bit(int bit_index, boolean new_value);
  /// Copy-on-write
  void copy_value();
  /** Ensures that if the bitstring length is not a multiple of 8 then
   *  the unused bits in the last byte are all cleared. */
  void clear_unused_bits() const;
  /// Creates a BITSTRING with pre-allocated but uninitialised memory.
  BITSTRING(int n_bits);

public:
  BITSTRING();
  BITSTRING(int init_n_bits, const unsigned char* init_bits);

  /** Copy constructor.
   *
   * @pre \p other_value must be bound */
  BITSTRING(const BITSTRING& other_value);

  /** Creates a BITSTRING with a single bit.
   * @pre \p other_value must be bound */
  BITSTRING(const BITSTRING_ELEMENT& other_value);

  ~BITSTRING();
  /// Decrement the reference count and free the memory if it's the last reference
  void clean_up();

  BITSTRING& operator=(const BITSTRING& other_value);
  BITSTRING& operator=(const BITSTRING_ELEMENT& other_value);

  boolean operator==(const BITSTRING& other_value) const;
  boolean operator==(const BITSTRING_ELEMENT& other_value) const;

  inline boolean operator!=(const BITSTRING& other_value) const
    { return !(*this == other_value); }
  inline boolean operator!=(const BITSTRING_ELEMENT& other_value) const
    { return !(*this == other_value); }

  BITSTRING operator+(const BITSTRING& other_value) const;
  BITSTRING operator+(const BITSTRING_ELEMENT& other_value) const;

  BITSTRING operator~() const;
  BITSTRING operator&(const BITSTRING& other_value) const;
  BITSTRING operator&(const BITSTRING_ELEMENT& other_value) const;
  BITSTRING operator|(const BITSTRING& other_value) const;
  BITSTRING operator|(const BITSTRING_ELEMENT& other_value) const;
  BITSTRING operator^(const BITSTRING& other_value) const;
  BITSTRING operator^(const BITSTRING_ELEMENT& other_value) const;

  BITSTRING operator<<(int shift_count) const;
  BITSTRING operator<<(const INTEGER& shift_count) const;
  BITSTRING operator>>(int shift_count) const;
  BITSTRING operator>>(const INTEGER& shift_count) const;
  BITSTRING operator<<=(int rotate_count) const;
  BITSTRING operator<<=(const INTEGER& rotate_count) const;
  BITSTRING operator>>=(int rotate_count) const;
  BITSTRING operator>>=(const INTEGER& rotate_count) const;

  BITSTRING_ELEMENT operator[](int index_value);
  BITSTRING_ELEMENT operator[](const INTEGER& index_value);
  const BITSTRING_ELEMENT operator[](int index_value) const;
  const BITSTRING_ELEMENT operator[](const INTEGER& index_value) const;

  inline boolean is_bound() const { return val_ptr != NULL; }
  inline boolean is_value() const { return val_ptr != NULL; }
  inline void must_bound(const char *err_msg) const
    { if (val_ptr == NULL) TTCN_error("%s", err_msg); }

  int lengthof() const;

  operator const unsigned char*() const;

  void log() const;

#ifdef TITAN_RUNTIME_2
  boolean is_equal(const Base_Type* other_value) const { return *this == *(static_cast<const BITSTRING*>(other_value)); }
  void set_value(const Base_Type* other_value) { *this = *(static_cast<const BITSTRING*>(other_value)); }
  Base_Type* clone() const { return new BITSTRING(*this); }
  const TTCN_Typedescriptor_t* get_descriptor() const { return &BITSTRING_descr_; }
  virtual int RAW_encode_negtest_raw(RAW_enc_tree& p_myleaf) const;
155
  Module_Param* get_param(Module_Param_Name& param_name) const;
Elemer Lelik's avatar
Elemer Lelik committed
156
157
158
159
160
#else
  inline boolean is_present() const { return is_bound(); }
#endif

  void set_param(Module_Param& param);
Elemer Lelik's avatar
Elemer Lelik committed
161
  
Elemer Lelik's avatar
Elemer Lelik committed
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
  void encode_text(Text_Buf& text_buf) const;
  void decode_text(Text_Buf& text_buf);

private:
  void BER_encode_putbits(unsigned char *target,
                          unsigned int bitnum_start,
                          unsigned int bit_count) const;

  void BER_decode_getbits(const unsigned char *source,
                          size_t s_len, unsigned int& bitnum_start);

  void BER_decode_TLV_(const ASN_BER_TLV_t& p_tlv, unsigned L_form,
                       unsigned int& bitnum_start);
public:
  void encode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
177
              int p_coding, ...) const;
Elemer Lelik's avatar
Elemer Lelik committed
178
179

  void decode(const TTCN_Typedescriptor_t& p_td, TTCN_Buffer& p_buf,
180
              int p_coding, ...);
Elemer Lelik's avatar
Elemer Lelik committed
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

  ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,
                                unsigned p_coding) const;

  boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td,
                         const ASN_BER_TLV_t& p_tlv, unsigned L_form);

  /** Encodes the value of the variable according to the
    * TTCN_Typedescriptor_t. It must be public because called by
    * another types during encoding. */
  int RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;
  /** Decodes the value of the variable according to the
   * TTCN_Typedescriptor_t. It must be public because called by
   * another types during encoding. Returns the number of decoded
   * bits. */
  int RAW_decode(const TTCN_Typedescriptor_t& , TTCN_Buffer&, int, raw_order_t,
197
     boolean no_err=FALSE, int sel_field=-1, boolean first_call=TRUE, const RAW_Force_Omit* force_omit = NULL);
Elemer Lelik's avatar
Elemer Lelik committed
198

199
  int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, unsigned int, int, embed_values_enc_struct_t*) const;
Elemer Lelik's avatar
Elemer Lelik committed
200
  int XER_decode(const XERdescriptor_t&, XmlReaderWrap& reader, unsigned int, unsigned int, embed_values_dec_struct_t*);
Elemer Lelik's avatar
Elemer Lelik committed
201
202
203
  
  /** Encodes accordingly to the JSON encoding rules.
    * Returns the length of the encoded data. */
204
  int JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean) const;
Elemer Lelik's avatar
Elemer Lelik committed
205
206
207
  
  /** Decodes accordingly to the JSON decoding rules.
    * Returns the length of the encoded data. */
208
  int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean, boolean, int p_chosen_field = CHOSEN_FIELD_UNSET);
209
210
211
212
213
214
215
216
  
  /** Encodes accordingly to the OER encoding rules.
    * Returns the length of the encoded data. */
  int OER_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;
  
  /** Decodes accordingly to the OER decoding rules.
    * Returns the length of the encoded data. */
  int OER_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&, OER_struct&);
Elemer Lelik's avatar
Elemer Lelik committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
};

class BITSTRING_ELEMENT {
  boolean bound_flag;
  BITSTRING& str_val;
  int bit_pos;

public:
  BITSTRING_ELEMENT(boolean par_bound_flag, BITSTRING& par_str_val,
                    int par_bit_pos);

  BITSTRING_ELEMENT& operator=(const BITSTRING& other_value);
  BITSTRING_ELEMENT& operator=(const BITSTRING_ELEMENT& other_value);

  boolean operator==(const BITSTRING& other_value) const;
  boolean operator==(const BITSTRING_ELEMENT& other_value) const;

  boolean operator!=(const BITSTRING& other_value) const
  { return !(*this == other_value); }
  boolean operator!=(const BITSTRING_ELEMENT& other_value) const
  { return !(*this == other_value); }

  BITSTRING operator+(const BITSTRING& other_value) const;
  BITSTRING operator+(const BITSTRING_ELEMENT& other_value) const;

  BITSTRING operator~() const;
  BITSTRING operator&(const BITSTRING& other_value) const;
  BITSTRING operator&(const BITSTRING_ELEMENT& other_value) const;
  BITSTRING operator|(const BITSTRING& other_value) const;
  BITSTRING operator|(const BITSTRING_ELEMENT& other_value) const;
  BITSTRING operator^(const BITSTRING& other_value) const;
  BITSTRING operator^(const BITSTRING_ELEMENT& other_value) const;

  inline boolean is_bound() const { return bound_flag; }
  inline boolean is_present() const { return bound_flag; }
  inline boolean is_value() const { return bound_flag; }
  inline void must_bound(const char *err_msg) const
    { if (!bound_flag) TTCN_error("%s", err_msg); }

  boolean get_bit() const;

  void log() const;
};

/// bitstring template class
262
263
struct decmatch_struct;

Elemer Lelik's avatar
Elemer Lelik committed
264
265
266
267
268
269
class BITSTRING_template : public Restricted_Length_Template {
#ifdef __SUNPRO_CC
public:
#endif
  struct bitstring_pattern_struct;
private:
270
#ifdef TITAN_RUNTIME_2
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  friend BITSTRING_template operator+(const BITSTRING& left_value,
    const BITSTRING_template& right_template);
  friend BITSTRING_template operator+(const BITSTRING_ELEMENT& left_value,
    const BITSTRING_template& right_template);
  friend BITSTRING_template operator+(template_sel left_template_sel,
    const BITSTRING_template& right_template);
  friend BITSTRING_template operator+(const BITSTRING& left_value,
    template_sel right_template_sel);
  friend BITSTRING_template operator+(const BITSTRING_ELEMENT& left_value,
    template_sel right_template_sel);
  friend BITSTRING_template operator+(template_sel left_template_sel,
    const BITSTRING& right_value);
  friend BITSTRING_template operator+(template_sel left_template_sel,
    const BITSTRING_ELEMENT& right_value);
285
#endif
286
  
Elemer Lelik's avatar
Elemer Lelik committed
287
288
289
290
291
292
293
  BITSTRING single_value;
  union {
    struct {
      unsigned int n_values;
      BITSTRING_template *list_value;
    } value_list;
    bitstring_pattern_struct *pattern_value;
294
    decmatch_struct* dec_match;
Elemer Lelik's avatar
Elemer Lelik committed
295
296
297
298
299
300
  };

  void copy_template(const BITSTRING_template& other_value);
  static boolean match_pattern(const bitstring_pattern_struct *string_pattern,
    const BITSTRING::bitstring_struct *string_value);

301
#ifdef TITAN_RUNTIME_2
302
303
304
  void concat(Vector<unsigned char>& v) const;
  static void concat(Vector<unsigned char>& v, const BITSTRING& val);
  static void concat(Vector<unsigned char>& v, template_sel sel);
305
#endif
306
  
Elemer Lelik's avatar
Elemer Lelik committed
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
public:
  BITSTRING_template();
  BITSTRING_template(template_sel other_value);
  BITSTRING_template(const BITSTRING& other_value);
  BITSTRING_template(const BITSTRING_ELEMENT& other_value);
  BITSTRING_template(const OPTIONAL<BITSTRING>& other_value);
  BITSTRING_template(unsigned int n_elements,
    const unsigned char *pattern_elements);
  BITSTRING_template(const BITSTRING_template& other_value);
  ~BITSTRING_template();
  void clean_up();

  BITSTRING_template& operator=(template_sel other_value);
  BITSTRING_template& operator=(const BITSTRING& other_value);
  BITSTRING_template& operator=(const BITSTRING_ELEMENT& other_value);
  BITSTRING_template& operator=(const OPTIONAL<BITSTRING>& other_value);
  BITSTRING_template& operator=(const BITSTRING_template& other_value);
324
  
325
#ifdef TITAN_RUNTIME_2
326
327
328
329
  BITSTRING_template operator+(const BITSTRING_template& other_value) const;
  BITSTRING_template operator+(const BITSTRING& other_value) const;
  BITSTRING_template operator+(const BITSTRING_ELEMENT& other_value) const;
  BITSTRING_template operator+(template_sel other_template_sel) const;
330
#endif
Elemer Lelik's avatar
Elemer Lelik committed
331
332
333
334
335
336

  BITSTRING_ELEMENT operator[](int index_value);
  BITSTRING_ELEMENT operator[](const INTEGER& index_value);
  const BITSTRING_ELEMENT operator[](int index_value) const;
  const BITSTRING_ELEMENT operator[](const INTEGER& index_value) const;

Elemer Lelik's avatar
Elemer Lelik committed
337
  boolean match(const BITSTRING& other_value, boolean legacy = FALSE) const;
Elemer Lelik's avatar
Elemer Lelik committed
338
339
340
341
  const BITSTRING& valueof() const;

  int lengthof() const;

342
  void set_type(template_sel template_type, unsigned int list_length = 0);
Elemer Lelik's avatar
Elemer Lelik committed
343
  BITSTRING_template& list_item(unsigned int list_index);
344
345
  
  void set_decmatch(Dec_Match_Interface* new_instance);
346
347
  
  void* get_decmatch_dec_res() const;
348
  const TTCN_Typedescriptor_t* get_decmatch_type_descr() const;
Elemer Lelik's avatar
Elemer Lelik committed
349
350

  void log() const;
Elemer Lelik's avatar
Elemer Lelik committed
351
  void log_match(const BITSTRING& match_value, boolean legacy = FALSE) const;
Elemer Lelik's avatar
Elemer Lelik committed
352
353
354
355
356
357

  void set_param(Module_Param& param);

  void encode_text(Text_Buf& text_buf) const;
  void decode_text(Text_Buf& text_buf);

Elemer Lelik's avatar
Elemer Lelik committed
358
359
  boolean is_present(boolean legacy = FALSE) const;
  boolean match_omit(boolean legacy = FALSE) const;
Elemer Lelik's avatar
Elemer Lelik committed
360
#ifdef TITAN_RUNTIME_2
361
  Module_Param* get_param(Module_Param_Name& param_name) const;
Elemer Lelik's avatar
Elemer Lelik committed
362
363
364
365
366
  void valueofv(Base_Type* value) const { *(static_cast<BITSTRING*>(value)) = valueof(); }
  void set_value(template_sel other_value) { *this = other_value; }
  void copy_value(const Base_Type* other_value) { *this = *(static_cast<const BITSTRING*>(other_value)); }
  Base_Template* clone() const { return new BITSTRING_template(*this); }
  const TTCN_Typedescriptor_t* get_descriptor() const { return &BITSTRING_descr_; }
Elemer Lelik's avatar
Elemer Lelik committed
367
368
  boolean matchv(const Base_Type* other_value, boolean legacy) const { return match(*(static_cast<const BITSTRING*>(other_value)), legacy); }
  void log_matchv(const Base_Type* match_value, boolean legacy) const  { log_match(*(static_cast<const BITSTRING*>(match_value)), legacy); }
Elemer Lelik's avatar
Elemer Lelik committed
369
#else
Elemer Lelik's avatar
Elemer Lelik committed
370
  void check_restriction(template_res t_res, const char* t_name=NULL, boolean legacy = FALSE) const;
Elemer Lelik's avatar
Elemer Lelik committed
371
372
373
#endif
};

374
#ifdef TITAN_RUNTIME_2
375
376
377
378
379
380
381
382
383
384
385
386
387
388
extern BITSTRING_template operator+(const BITSTRING& left_value,
  const BITSTRING_template& right_template);
extern BITSTRING_template operator+(const BITSTRING_ELEMENT& left_value,
  const BITSTRING_template& right_template);
extern BITSTRING_template operator+(template_sel left_template_sel,
  const BITSTRING_template& right_template);
extern BITSTRING_template operator+(const BITSTRING& left_value,
  template_sel right_template_sel);
extern BITSTRING_template operator+(const BITSTRING_ELEMENT& left_value,
  template_sel right_template_sel);
extern BITSTRING_template operator+(template_sel left_template_sel,
  const BITSTRING& right_value);
extern BITSTRING_template operator+(template_sel left_template_sel,
  const BITSTRING_ELEMENT& right_value);
389
#endif
390

Elemer Lelik's avatar
Elemer Lelik committed
391
#endif