Merge pull request #63 from BenceJanosSzabo/master
[deliverable/titan.core.git] / core / Encdec.hh
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 * Baji, Laszlo
10 * Balasko, Jeno
11 * Baranyi, Botond
12 * Forstner, Matyas
13 * Kovacs, Ferenc
14 * Raduly, Csaba
15 * Szabados, Kristof
16 * Szabo, Janos Zoltan – initial implementation
17 * Szalai, Gabor
18 *
19 ******************************************************************************/
20 #ifndef ENCDEC_HH
21 #define ENCDEC_HH
22
23 #include "Types.h"
24
25 typedef const unsigned char cbyte;
26
27
28 class OCTETSTRING;
29 class CHARSTRING;
30 class UNIVERSAL_CHARSTRING;
31 struct RAW_coding_par;
32
33 /** Endianness indicator */
34 enum raw_order_t {
35 ORDER_MSB,
36 ORDER_LSB
37 };
38
39 /**
40 * Static class which encapsulates the stuff related to
41 * encoding/decoding.
42 */
43 class TTCN_EncDec {
44 public:
45 /** Coding types. */
46 enum coding_t {
47 CT_BER, /**< BER */
48 CT_PER, /**< PER */
49 CT_RAW, /**< RAW */
50 CT_TEXT, /**< TEXT */
51 CT_XER, /**< XER */
52 CT_JSON /**< JSON */
53 };
54 /** Error type enum type. If you want to add new values, please put
55 * them before ET_ALL. Values must be consecutive, starting at zero.
56 * When adding a new value, a corresponding string (without "ET_")
57 * must be added to compiler2/ttcn3/Ttcnstuff.cc */
58 enum error_type_t {
59 ET_UNDEF = 0, /**< Undefined error. */
60 ET_UNBOUND = 1, /**< Encoding of an unbound value. */
61 ET_INCOMPL_ANY, /**< Encoding of an ASN ANY value which does not
62 contain a valid BER TLV. */
63 ET_ENC_ENUM, /**< Encoding of an unknown enumerated value. */
64 ET_INCOMPL_MSG, /**< Decode error: incomplete message. */
65 ET_LEN_FORM, /**< During decoding: the received message has a
66 non-acceptable length form (BER). 5*/
67 ET_INVAL_MSG, /**< Decode error: invalid message. */
68 ET_REPR, /**< Representation error, e.g.: internal
69 representation of integral numbers. */
70 ET_CONSTRAINT, /**< The value breaks some constraint. */
71 ET_TAG, /**< During decoding: unexpected tag. */
72 ET_SUPERFL, /**< During decoding: superfluous part
73 detected. In case of BER, this can be
74 superfluous TLV at the end of a constructed
75 TLV. 10 */
76 ET_EXTENSION, /**< During decoding: there was something in the
77 extension (e.g.: in ASN.1 ellipsis). */
78 ET_DEC_ENUM, /**< During decoding of an (inextensible)
79 enumerated value: unknown value received. */
80 ET_DEC_DUPFLD, /**< During decoding: duplicated field. For
81 example, while decoding a SET type. */
82 ET_DEC_MISSFLD, /**< During decoding: missing field. For example,
83 while decoding a SET type. */
84 ET_DEC_OPENTYPE, /**< Cannot decode an opentype (broken component
85 relation constraint). 15 */
86 ET_DEC_UCSTR, /**< During decoding a universal charstring:
87 something went wrong. */
88 ET_LEN_ERR, /**< During RAW encoding: the specified field
89 length is not enough to encode the value of
90 the field. During RAW decoding: the available
91 number of bits is less than it needed to
92 decode the field. */
93 ET_SIGN_ERR, /**< Unsigned encoding of a negative number. */
94 ET_INCOMP_ORDER, /**< Incompatible combination of orders attribute
95 for RAW coding. */
96 ET_TOKEN_ERR, /**< During TEXT decoding the specified token is
97 not found. 20 */
98 ET_LOG_MATCHING, /**< During TEXT decoding the matching is logged
99 if the behavior was set to EB_WARNING. */
100 ET_FLOAT_TR, /**< The float value will be truncated during
101 double -> single precision conversion */
102 ET_FLOAT_NAN, /**< Not a Number has been received */
103 ET_OMITTED_TAG, /**< During encoding the key of a tag references
104 an optional field with omitted value */
105 ET_NEGTEST_CONFL, /**< Contradictory negative testing and RAW attributes. */
106 ET_ALL, /**< Used only when setting error behavior. 25 */
107 ET_INTERNAL, /**< Internal error. Error behavior cannot be set
108 for this. */
109 ET_NONE /**< There was no error. */
110 };
111 /** Error behavior enum type. */
112 enum error_behavior_t {
113 EB_DEFAULT, /**< Used only when setting error behavior. */
114 EB_ERROR, /**< Raises an error. */
115 EB_WARNING, /**< Logs the error but continues the activity. */
116 EB_IGNORE /**< Totally ignores the error. */
117 };
118
119 /** @brief Set the error behaviour for encoding/decoding functions
120 *
121 * @param p_et error type
122 * @param p_eb error behaviour
123 */
124 static void set_error_behavior(error_type_t p_et, error_behavior_t p_eb);
125
126 /** @brief Get the current error behaviour
127 *
128 * @param p_et error type
129 * @return error behaviour for the supplied error type
130 */
131 static error_behavior_t get_error_behavior(error_type_t p_et);
132
133 /** @brief Get the default error behaviour
134 *
135 * @param p_et error type
136 * @return default error behaviour for the supplied error type
137 */
138 static error_behavior_t get_default_error_behavior(error_type_t p_et);
139
140 /** @brief Get the last error code.
141 *
142 * @return last_error_type
143 */
144 static error_type_t get_last_error_type() { return last_error_type; }
145
146 /** @brief Get the error string corresponding to the last error.
147 *
148 * @return error_str
149 */
150 static const char* get_error_str() { return error_str; }
151
152 /** @brief Set a clean slate
153 *
154 * Sets last_error_type to ET_NONE.
155 * Frees error_str.
156 */
157 static void clear_error();
158
159 /* The stuff below this line is for internal use only */
160 static void error(error_type_t p_et, char *msg);
161
162 private:
163 /** Default error behaviours for all error types */
164 static const error_behavior_t default_error_behavior[ET_ALL];
165
166 /** Current error behaviours for all error types */
167 static error_behavior_t error_behavior[ET_ALL];
168
169 /** Last error value */
170 static error_type_t last_error_type;
171
172 /** Error string for the last error */
173 static char *error_str;
174 };
175
176 /** @brief Error context
177 *
178 * Maintains a list of linked TTCN_EncDec_ErrorContext objects
179 *
180 */
181 class TTCN_EncDec_ErrorContext {
182 private:
183 /** Variables for the linked list */
184 static TTCN_EncDec_ErrorContext *head, *tail;
185
186 /** Pointers for the linked list */
187 TTCN_EncDec_ErrorContext *prev, *next;
188
189 /** */
190 char *msg;
191 /// Copy constructor disabled
192 TTCN_EncDec_ErrorContext(const TTCN_EncDec_ErrorContext&);
193 /// Assignment disabled
194 TTCN_EncDec_ErrorContext& operator=(const TTCN_EncDec_ErrorContext&);
195 public:
196 /** @brief Default constructor.
197 *
198 * Adds this object of the end of the list
199 *
200 * @post msg == 0
201 * @post tail == this
202 *
203 */
204 TTCN_EncDec_ErrorContext();
205
206 /** @brief Constructor.
207 *
208 * Adds this object of the end of the list
209 * and sets msg.
210 *
211 * @post msg != 0
212 * @post tail == this
213 *
214 * @param fmt printf-like format string
215 * @param ... printf-like parameters
216 */
217 TTCN_EncDec_ErrorContext(const char *fmt, ...)
218 __attribute__ ((__format__ (__printf__, 2, 3))); // 'this' is at index 1
219
220 /** @brief Destructor.
221 *
222 * Removes this object from the end of the list
223 *
224 * @pre tail == this
225 *
226 */
227 ~TTCN_EncDec_ErrorContext();
228
229 /** @brief Replaces msg with a new string
230 *
231 * Calls Free, then mprintf_va_list
232 *
233 * @param fmt printf-like format string
234 * @param ... printf-like parameters
235 */
236 void set_msg(const char *fmt, ...)
237 __attribute__ ((__format__ (__printf__, 2, 3))); // 'this' is at index 1
238
239 /** @brief Collects error strings from all active error contexts and logs an error
240 *
241 * If the error behaviour for \p p_et is not TTCN_EncDec::EB_IGNORE, then
242 * walks the list of TTCN_EncDec_ErrorContext and concatenates the error messages,
243 * then calls TTCN_EncDec::error
244 *
245 * @param p_et a TTCN_EncDec::error_type_t error type
246 * @param fmt printf-like format string
247 * @param ... printf-like parameters
248 *
249 */
250 static void error(TTCN_EncDec::error_type_t p_et, const char *fmt, ...)
251 __attribute__ ((__format__ (__printf__, 2, 3)));
252 static void error_internal(const char *fmt, ...)
253 __attribute__ ((__format__ (__printf__, 1, 2), __noreturn__));
254 static void warning(const char *fmt, ...)
255 __attribute__ ((__format__ (__printf__, 1, 2)));
256 };
257
258 /**
259 * Buffer used by the different encoders/decoders.
260 */
261 class TTCN_Buffer {
262 private:
263 struct buffer_struct; // no user serviceable parts
264 buffer_struct *buf_ptr; ///< pointer to internal data
265 size_t buf_size;///< The number of bytes of memory allocated
266 size_t buf_len; ///< The number of bytes of memory used (buf_len <= buf_size)
267 size_t buf_pos; ///< Read offset in bytes in the buffer (buf_pos <= buf_len)
268 size_t bit_pos; ///< Read offset of the current bit inside the byte at buf_pos
269 size_t last_bit_pos;
270 size_t last_bit_bitpos;
271 size_t start_of_ext_bit;
272 boolean last_bit; ///< the state of the "last bit" (only after get_b was called)
273 boolean current_bitorder; ///< \c true for TOP_BIT_LEFT
274 boolean ext_bit_reverse; ///< \c true if 0 signals the end
275 unsigned int ext_level;
276
277 /** Resets all fields except the size and length indicators. */
278 void reset_buffer();
279 /** Deallocates the memory area that is associated with the buffer. */
280 void release_memory();
281 /** Returns the smallest preferred size of the allocated memory area
282 * that is at least \a target_size. */
283 static size_t get_memory_size(size_t target_size);
284 /** Ensures that buffer has its own writable memory area. */
285 void copy_memory();
286 /** Ensures that there are at least \a target_size writable bytes in the
287 * memory area after \a buf_len. */
288 void increase_size(size_t size_incr);
289
290 public:
291 /** Creates an empty buffer. */
292 TTCN_Buffer();
293 /** Copy constructor. */
294 TTCN_Buffer(const TTCN_Buffer& p_buf);
295 /** Initializes the buffer with the contents of \a p_os.
296 * @pre The argument must be bound. */
297 TTCN_Buffer(const OCTETSTRING& p_os);
298 /** Initializes the buffer with the contents of \a p_cs.
299 * @pre The argument must be bound. */
300 TTCN_Buffer(const CHARSTRING& p_cs);
301 /** Destructor. */
302 ~TTCN_Buffer() { release_memory(); }
303 /** Copies the contents of \a p_buf into \a this.
304 * The read pointers and other attributes are reset. */
305 TTCN_Buffer& operator=(const TTCN_Buffer& p_buf);
306 /** Copies the contents of \a p_os into \a this.
307 * The read pointers and other attributes are reset. */
308 TTCN_Buffer& operator=(const OCTETSTRING& p_os);
309 /** Copies the contents of \a p_cs into \a this.
310 * The read pointers and other attributes are reset. */
311 TTCN_Buffer& operator=(const CHARSTRING& p_cs);
312 /** Erases the content of the buffer. */
313 void clear();
314 /** Returns how many bytes are in the buffer. */
315 inline size_t get_len() const { return buf_len; }
316 /** Returns a pointer to the beginning of data. */
317 const unsigned char* get_data() const;
318 /** Returns how many bytes are in the buffer to read. */
319 inline size_t get_read_len() const { return buf_len - buf_pos; }
320 /** Returns a pointer which points to read position of data. */
321 const unsigned char* get_read_data() const;
322 /** Sets the read position to the beginning of the buffer. */
323 inline void rewind() { buf_pos = 0; bit_pos = 0; }
324 /** Returns the (reading) position of the buffer. */
325 inline size_t get_pos() const { return buf_pos; }
326 /** Sets the (reading) position to \a pos, or to the end of buffer,
327 * if pos > len. */
328 void set_pos(size_t pos);
329 /** Increases the (reading) position by \a delta, or sets it to the
330 * end of buffer, if get_pos() + delta > len. */
331 void increase_pos(size_t delta);
332 /** You can write up to \a end_len chars beginning from \a end_ptr;
333 * after writing, you have to call also increase_length()! Useful
334 * if you want to use memcpy. @see increase_length(). \param
335 * end_ptr out. \param end_len inout. */
336 void get_end(unsigned char*& end_ptr, size_t& end_len);
337 /** How many chars have you written after a get_end(), beginning
338 * from end_ptr. @see get_end() */
339 void increase_length(size_t size_incr);
340 /** Appends single character \a c to the buffer. */
341 void put_c(unsigned char c);
342 /** Appends \a len bytes starting from address \a s to the buffer. */
343 void put_s(size_t len, const unsigned char *s);
344 /** Appends the contents of octetstring \a p_os to the buffer. */
345 void put_string(const OCTETSTRING& p_os);
346 /** Same as \a put_string(). Provided only for backward compatibility. */
347 inline void put_os(const OCTETSTRING& p_os) { put_string(p_os); }
348 /** Appends the contents of charstring \a p_cs to the buffer. */
349 void put_string(const CHARSTRING& p_cs);
350 /** Same as \a put_string(). Provided only for backward compatibility. */
351 inline void put_cs(const CHARSTRING& p_cs) { put_string(p_cs); }
352 /** Appends the content of \a p_buf to the buffer */
353 void put_buf(const TTCN_Buffer& p_buf);
354 /** Stores the current contents of the buffer to variable \a p_os. */
355 void get_string(OCTETSTRING& p_os);
356 /** Stores the current contents of the buffer to variable \a p_cs. */
357 void get_string(CHARSTRING& p_cs);
358 /** Stores the current contents of the buffer to variable \a p_cs. */
359 void get_string(UNIVERSAL_CHARSTRING& p_cs);
360 /** Cuts the bytes between the beginning of the buffer and the read
361 * position. After that the read position will point to the beginning
362 * of the updated buffer. */
363 void cut();
364 /** Cuts the bytes between the read position and the end of the buffer.
365 * The read position remains unchanged (i.e. it will point to the end
366 * of the truncated buffer. */
367 void cut_end();
368 /** Returns whether the buffer (beginning from the read position)
369 * contains a complete TLV. */
370 boolean contains_complete_TLV();
371
372 /* The members below this line are for internal use only. */
373 /* ------------------------------------------------------ */
374
375 void log() const;
376
377 /** Puts a bit string in the buffer. Use only this function if you
378 * use the buffer as bit buffer.
379 *
380 * @param len number of _bits_ to write
381 * @param s pointer to the data (bytes)
382 * @param coding_par
383 * @param align alignment length (in ???)
384 */
385 void put_b(size_t len, const unsigned char *s,
386 const RAW_coding_par& coding_par, int align);
387 /** Reads a bit string from the buffer. Use only this function if you
388 * use the buffer as bit buffer. */
389 void get_b(size_t len, unsigned char *s, const RAW_coding_par& coding_par,
390 raw_order_t top_bit_order);
391 /** Puts @p len number of zeros in the buffer. */
392 void put_zero(size_t len, raw_order_t fieldorder);
393 /** Returns a pointer which points to read position of data and the
394 * starting position of the bitstring within first the octet. */
395 const unsigned char* get_read_data(size_t& bitpos) const;
396 /** Sets the (reading) position to \a pos and the bit position to \a
397 * bit_pos, or to the end of buffer, if pos > len. */
398 void set_pos(size_t pos, size_t bitpos);
399 /** Sets the (reading) position to \a pos
400 * or to the end of buffer, if pos > len. */
401 void set_pos_bit(size_t new_bit_pos);
402 /** Returns the (reading) position of the buffer in bits. */
403 inline size_t get_pos_bit() const { return buf_pos * 8 + bit_pos; }
404 /** Increases the (reading) position by \a delta bits, or sets it to
405 * the end of buffer, if get_pos() + delta > len. */
406 void increase_pos_bit(size_t delta);
407 /** Increases the (reading) position to a multiple of \p padding.
408 * @return the number of bits used up. */
409 int increase_pos_padd(int padding);
410 /** Returns the number of bits remaining in the buffer */
411 size_t unread_len_bit();
412 /** Mark the start of extension bit processing during encoding. */
413 void start_ext_bit(boolean p_reverse);
414 /** Apply the extension bit to the encoded bytes. */
415 void stop_ext_bit();
416 inline boolean get_order() const { return current_bitorder; }
417 inline void set_order(boolean new_order) { current_bitorder = new_order; }
418 void put_pad(size_t len, const unsigned char *s, int pat_len,
419 raw_order_t fieldorder);
420 void set_last_bit(boolean p_last_bit);
421 inline boolean get_last_bit() const { return last_bit; }
422
423 private:
424 static unsigned char get_byte_rev(const unsigned char* data, size_t len,
425 size_t index);
426 unsigned char get_byte_align(size_t len, raw_order_t fieldorder,
427 raw_order_t req_align ,size_t index);
428 };
429
430 #endif
This page took 0.047678 seconds and 5 git commands to generate.