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
15 * Szabo, Janos Zoltan – initial implementation
18 ******************************************************************************/
20 #include "../common/memory.h"
24 #include "Basetype.hh"
27 #include <openssl/bn.h>
29 const unsigned char BitReverseTable
[256] =
31 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
32 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
33 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
34 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
35 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
36 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
37 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
38 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
39 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
40 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
41 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
42 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
43 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
44 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
45 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
46 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
47 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
48 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
49 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
50 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
51 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
52 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
53 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
54 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
55 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
56 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
57 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
58 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
59 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
60 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
61 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
62 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
65 const unsigned char BitMaskTable
[9]={
66 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
70 * Initialize the RAW encoding tree. The tree representations makes it easier
71 * to encode/decode structured types with various attributes. Each node in the
72 * tree stores information about the node's parent, position, attributes,
73 * child nodes etc. The root of the tree is on the first level and its ``par''
74 * is always NULL. That's why there's a ``par_pos'' parameter, but it could be
75 * omitted. The first part of the position route in ``curr_pos.pos'' is
76 * inherited from ``par''. The last element is the number of the current
77 * element. Only the leaves carry data. Other nodes are just for construction
80 * @param is_leaf true if it's a node with no children
81 * @param par the parent of the current node
82 * @param par_pos the parent's position
83 * @param my_pos the child node's number of ``par''
84 * @param raw_attr encoding attributes
86 RAW_enc_tree::RAW_enc_tree(boolean is_leaf
, RAW_enc_tree
*par
,
87 RAW_enc_tr_pos
*par_pos
, int my_pos
, const TTCN_RAWdescriptor_t
*raw_attr
)
92 data_ptr_used
= false;
95 curr_pos
.pos
= (int*) Malloc((par_pos
->level
+1)*sizeof(int));
96 if (par_pos
->level
) memcpy((void*) curr_pos
.pos
, (void*) par_pos
->pos
,
97 par_pos
->level
* sizeof(int));
98 curr_pos
.level
= par_pos
->level
+ 1;
99 curr_pos
.pos
[curr_pos
.level
- 1] = my_pos
;
101 padding
= raw_attr
->padding
;
102 prepadding
= raw_attr
->prepadding
;
103 padding_pattern_length
= raw_attr
->padding_pattern_length
;
104 padding_pattern
= raw_attr
->padding_pattern
;
109 ext_bit_handling
= 0;
111 ext_bit
= raw_attr
->extension_bit
;
112 top_bit_order
= raw_attr
->top_bit_order
;
114 if (raw_attr
->byteorder
== ORDER_MSB
) orders
= true;
115 if (raw_attr
->bitorderinfield
== ORDER_MSB
) orders
= !orders
;
116 coding_par
.byteorder
= orders
? ORDER_MSB
: ORDER_LSB
;
118 if (raw_attr
->bitorderinoctet
== ORDER_MSB
) orders
= true;
119 if (raw_attr
->bitorderinfield
== ORDER_MSB
) orders
= !orders
;
120 coding_par
.bitorder
= orders
? ORDER_MSB
: ORDER_LSB
;
121 coding_par
.hexorder
= raw_attr
->hexorder
;
122 coding_par
.fieldorder
= raw_attr
->fieldorder
;
124 body
.leaf
.data_ptr
= NULL
;
127 body
.node
.num_of_nodes
= 0;
128 body
.node
.nodes
= NULL
;
132 RAW_enc_tree::~RAW_enc_tree()
135 if (must_free
) Free(body
.leaf
.data_ptr
);
138 for (int a
= 0; a
< body
.node
.num_of_nodes
; a
++) {
139 if (body
.node
.nodes
[a
] != NULL
) delete body
.node
.nodes
[a
];
141 Free(body
.node
.nodes
);
145 Free(calcof
.lengthto
.fields
);
155 void RAW_enc_tree::put_to_buf(TTCN_Buffer
&buf
){
156 //printf("Start put_to_buf\n\r");
158 //printf("End padding\n\r");
160 //printf("End calc\n\r");
162 //printf("End fill\n\r");
165 void RAW_enc_tree::calc_fields()
172 if (calcof
.lengthto
.unit
!= -1) {
173 for (int a
= 0; a
< calcof
.lengthto
.num_of_fields
; a
++) {
174 atm
= get_node(calcof
.lengthto
.fields
[a
]);
175 if (atm
) szumm
+= atm
->length
+ atm
->padlength
+ atm
->prepadlength
;
177 szumm
= (szumm
+ calcof
.lengthto
.unit
- 1) / calcof
.lengthto
.unit
;
180 atm
= get_node(calcof
.lengthto
.fields
[0]);
181 if (atm
) szumm
= atm
->body
.node
.num_of_nodes
;
184 temp
.RAW_encode(*coding_descr
, *this);
187 int cl
= curr_pos
.pos
[curr_pos
.level
- 1];
188 curr_pos
.pos
[curr_pos
.level
- 1] = calcof
.pointerto
.ptr_base
;
189 int base
= calcof
.pointerto
.ptr_base
;
190 RAW_enc_tree
*b
= get_node(curr_pos
);
193 curr_pos
.pos
[curr_pos
.level
- 1] = base
;
194 b
= get_node(curr_pos
);
196 curr_pos
.pos
[curr_pos
.level
- 1] = cl
;
197 atm
= get_node(calcof
.pointerto
.target
);
198 if (atm
) szumm
= (atm
->startpos
- b
->startpos
+ calcof
.pointerto
.unit
- 1
199 - calcof
.pointerto
.ptr_offset
) / calcof
.pointerto
.unit
;
201 temp
.RAW_encode(*coding_descr
, *this);
208 for (int a
= 0; a
< body
.node
.num_of_nodes
; a
++)
209 if (body
.node
.nodes
[a
]) body
.node
.nodes
[a
]->calc_fields();
213 int RAW_enc_tree::calc_padding(int position
)
215 int current_pos
= position
;
218 int new_pos
= ((current_pos
+ prepadding
- 1) / prepadding
) * prepadding
;
219 prepadlength
= new_pos
- position
;
220 current_pos
= new_pos
;
223 for (int a
= 0; a
< body
.node
.num_of_nodes
; a
++) {
224 if (body
.node
.nodes
[a
]) {
225 current_pos
= body
.node
.nodes
[a
]->calc_padding(current_pos
);
228 length
= current_pos
- position
- prepadlength
;
230 else current_pos
+= length
;
232 int new_pos
= ((current_pos
+ padding
- 1) / padding
) * padding
;
233 padlength
= new_pos
- length
- position
- prepadlength
;
234 current_pos
= new_pos
;
239 void RAW_enc_tree::fill_buf(TTCN_Buffer
&buf
)
241 boolean old_order
= buf
.get_order();
242 if (top_bit_order
!= TOP_BIT_INHERITED
) buf
.set_order(top_bit_order
244 buf
.put_pad(prepadlength
, padding_pattern
, padding_pattern_length
,
245 coding_par
.fieldorder
);
247 //printf("align: %d, length: %d\n\r",align,length);
248 int align_length
= align
< 0 ? -align
: align
;
249 if (ext_bit
!= EXT_BIT_NO
) buf
.start_ext_bit(ext_bit
== EXT_BIT_REVERSE
);
250 // if(ext_bit_handling%2) buf.start_ext_bit(ext_bit==EXT_BIT_REVERSE);
252 buf
.put_b(length
- align_length
, body
.leaf
.data_ptr
, coding_par
, align
);
254 buf
.put_b(length
- align_length
, body
.leaf
.data_array
, coding_par
, align
);
255 if (ext_bit_handling
> 1)
257 else if (ext_bit
!= EXT_BIT_NO
&& !ext_bit_handling
) buf
.stop_ext_bit();
260 if (ext_bit
!= EXT_BIT_NO
&& (!rec_of
|| ext_bit_handling
% 2))
261 buf
.start_ext_bit(ext_bit
== EXT_BIT_REVERSE
);
262 for (int a
= 0; a
< body
.node
.num_of_nodes
; a
++) {
263 if (body
.node
.nodes
[a
]) body
.node
.nodes
[a
]->fill_buf(buf
);
264 if (ext_bit
!= EXT_BIT_NO
&& rec_of
&& !ext_bit_handling
)
265 buf
.set_last_bit(ext_bit
!= EXT_BIT_YES
);
267 if (!ext_bit_handling
) {
268 if (ext_bit
!= EXT_BIT_NO
&& !rec_of
)
270 else if (ext_bit
!= EXT_BIT_NO
&& rec_of
)
271 buf
.set_last_bit(ext_bit
== EXT_BIT_YES
);
273 else if (ext_bit_handling
> 1) buf
.stop_ext_bit();
275 buf
.put_pad(padlength
, padding_pattern
, padding_pattern_length
,
276 coding_par
.fieldorder
);
277 buf
.set_order(old_order
);
281 * Return the element at ``req_pos'' from the RAW encoding tree. At first get
282 * the root of the whole tree at the first level. Then go down in the tree
283 * following the route in the ``req_pos.pos'' array. If the element was not
284 * found NULL is returned.
286 * @param req_pos the position of the element
287 * @return the element at the given position
289 RAW_enc_tree
* RAW_enc_tree::get_node(RAW_enc_tr_pos
&req_pos
)
291 if (req_pos
.level
== 0) return NULL
;
292 RAW_enc_tree
* t
= this;
293 int cur_level
= curr_pos
.level
;
294 for (int b
= 1; b
< cur_level
; b
++) t
= t
->parent
;
295 for (cur_level
= 1; cur_level
< req_pos
.level
; cur_level
++) {
296 if (!t
|| t
->isleaf
|| t
->body
.node
.num_of_nodes
<= req_pos
.pos
[cur_level
]) return NULL
;
297 t
= t
->body
.node
.nodes
[req_pos
.pos
[cur_level
]];
303 * Return the number of bits needed to represent an integer value `a'. The
304 * sign bit is added for negative values. It has a different implementation
305 * for `BIGNUM' values.
307 * @param a the integer in question
308 * @return the number of bits needed to represent the given integer
313 register int bits
= 0;
314 register int tmp
= a
;
326 int min_bits(BIGNUM
*a
)
329 register int bits
= BN_num_bits(a
) + BN_is_negative(a
);
333 // Called from code generated by enum.c (defEnumClass)
334 int RAW_encode_enum_type(const TTCN_Typedescriptor_t
& p_td
,
335 RAW_enc_tree
& myleaf
, int integer_value
, int min_bits_enum
)
337 int fl
= p_td
.raw
->fieldlength
? p_td
.raw
->fieldlength
: min_bits_enum
;
338 TTCN_RAWdescriptor_t my_raw
;
339 my_raw
.fieldlength
= fl
;
340 my_raw
.comp
= p_td
.raw
->comp
;
341 my_raw
.byteorder
= p_td
.raw
->byteorder
;
342 my_raw
.endianness
= p_td
.raw
->endianness
;
343 my_raw
.bitorderinfield
= p_td
.raw
->bitorderinfield
;
344 my_raw
.bitorderinoctet
= p_td
.raw
->bitorderinoctet
;
345 my_raw
.extension_bit
= p_td
.raw
->extension_bit
;
346 my_raw
.hexorder
= p_td
.raw
->hexorder
;
347 my_raw
.fieldorder
= p_td
.raw
->fieldorder
;
348 my_raw
.top_bit_order
= p_td
.raw
->top_bit_order
;
349 my_raw
.padding
= p_td
.raw
->padding
;
350 my_raw
.prepadding
= p_td
.raw
->prepadding
;
351 my_raw
.ptroffset
= p_td
.raw
->ptroffset
;
352 my_raw
.unit
= p_td
.raw
->unit
;
353 TTCN_Typedescriptor_t my_descr
= { p_td
.name
, 0, &my_raw
, NULL
, NULL
, NULL
,
354 NULL
, TTCN_Typedescriptor_t::DONTCARE
};
355 INTEGER
i(integer_value
);
356 i
.RAW_encode(my_descr
, myleaf
);
357 // myleaf.align=0;//p_td.raw->endianness==ORDER_MSB?min_bits_enum-fl:fl-min_bits_enum;
358 return myleaf
.length
= fl
;
361 // Called from code generated by enum.c (defEnumClass)
362 int RAW_decode_enum_type(const TTCN_Typedescriptor_t
& p_td
, TTCN_Buffer
& buff
,
363 int limit
, raw_order_t top_bit_ord
, int& value
, int min_bits_enum
,
366 int fl
= p_td
.raw
->fieldlength
? p_td
.raw
->fieldlength
: min_bits_enum
;
367 TTCN_RAWdescriptor_t my_raw
;
368 my_raw
.fieldlength
= fl
;
369 my_raw
.comp
= p_td
.raw
->comp
;
370 my_raw
.byteorder
= p_td
.raw
->byteorder
;
371 my_raw
.endianness
= p_td
.raw
->endianness
;
372 my_raw
.bitorderinfield
= p_td
.raw
->bitorderinfield
;
373 my_raw
.bitorderinoctet
= p_td
.raw
->bitorderinoctet
;
374 my_raw
.extension_bit
= p_td
.raw
->extension_bit
;
375 my_raw
.hexorder
= p_td
.raw
->hexorder
;
376 my_raw
.fieldorder
= p_td
.raw
->fieldorder
;
377 my_raw
.top_bit_order
= p_td
.raw
->top_bit_order
;
378 my_raw
.padding
= p_td
.raw
->padding
;
379 my_raw
.prepadding
= p_td
.raw
->prepadding
;
380 my_raw
.ptroffset
= p_td
.raw
->ptroffset
;
381 my_raw
.unit
= p_td
.raw
->unit
;
382 TTCN_Typedescriptor_t my_descr
= { p_td
.name
, 0, &my_raw
, NULL
, NULL
, NULL
,
383 NULL
, TTCN_Typedescriptor_t::DONTCARE
};
385 /* if(p_td.raw->endianness==ORDER_MSB)
386 buff.increase_pos_bit(fl-min_bits_enum);*/
387 fl
= i
.RAW_decode(my_descr
, buff
, limit
, top_bit_ord
, no_err
);
388 if (fl
< 0) return fl
;
390 /* if(p_td.raw->endianness==ORDER_LSB)
391 buff.increase_pos_bit(fl-min_bits_enum);*/
392 return fl
+ buff
.increase_pos_padd(p_td
.raw
->padding
);
395 RAW_enc_tree
** init_nodes_of_enc_tree(int nodes_num
)
397 RAW_enc_tree
** ret_val
=(RAW_enc_tree
**) Malloc(nodes_num
*sizeof(RAW_enc_tree
*));
398 memset(ret_val
,0,nodes_num
*sizeof(RAW_enc_tree
*));
402 RAW_enc_tr_pos
* init_lengthto_fields_list(int num
){
403 return (RAW_enc_tr_pos
*)Malloc(num
*sizeof(RAW_enc_tr_pos
));
406 int* init_new_tree_pos(RAW_enc_tr_pos
&old_pos
,int new_levels
, int* new_pos
){
407 int *new_position
=(int*)Malloc((old_pos
.level
+new_levels
)*sizeof(int));
408 memcpy(new_position
,old_pos
.pos
,old_pos
.level
*sizeof(int));
409 memcpy(new_position
+old_pos
.level
,new_pos
,new_levels
*sizeof(int));
413 void free_tree_pos(int* ptr
){
417 int min_of_ints(int num_of_int
,...)
420 va_start(pvar
,num_of_int
);
422 if (num_of_int
> 0) {
423 min_val
= va_arg(pvar
, int);
424 for (int a
= 1; a
< num_of_int
; a
++) {
425 int b
= va_arg(pvar
, int);
426 if (b
< min_val
) min_val
= b
;
433 /** Default descriptors of RAW encoding for primitive types. padding
437 * | | padding_pattern_length
438 * | | padding_pattern
439 * length,comp ,byteorder,align ,ord_field,ord_octet,ext_bit ,hexorder,fieldorder,top_bit, | | length_restriction*/
440 const TTCN_RAWdescriptor_t INTEGER_raw_
= {8,SG_NO
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,EXT_BIT_NO
,ORDER_LSB
,ORDER_LSB
,TOP_BIT_INHERITED
,0,0,0,8,0,NULL
,-1};
441 const TTCN_RAWdescriptor_t BOOLEAN_raw_
= {1,SG_NO
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,EXT_BIT_NO
,ORDER_LSB
,ORDER_LSB
,TOP_BIT_INHERITED
,0,0,0,8,0,NULL
,-1};
442 const TTCN_RAWdescriptor_t BITSTRING_raw_
= {0,SG_NO
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,EXT_BIT_NO
,ORDER_LSB
,ORDER_LSB
,TOP_BIT_INHERITED
,0,0,0,8,0,NULL
,-1};
443 const TTCN_RAWdescriptor_t OCTETSTRING_raw_
= {0,SG_NO
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,EXT_BIT_NO
,ORDER_LSB
,ORDER_LSB
,TOP_BIT_INHERITED
,0,0,0,8,0,NULL
,-1};
444 const TTCN_RAWdescriptor_t HEXSTRING_raw_
= {0,SG_NO
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,EXT_BIT_NO
,ORDER_LSB
,ORDER_LSB
,TOP_BIT_INHERITED
,0,0,0,8,0,NULL
,-1};
445 const TTCN_RAWdescriptor_t CHARSTRING_raw_
= {0,SG_NO
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,EXT_BIT_NO
,ORDER_LSB
,ORDER_LSB
,TOP_BIT_INHERITED
,0,0,0,8,0,NULL
,-1};
446 const TTCN_RAWdescriptor_t FLOAT_raw_
= {64,SG_NO
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,EXT_BIT_NO
,ORDER_LSB
,ORDER_LSB
,TOP_BIT_INHERITED
,0,0,0,8,0,NULL
,-1};
447 const TTCN_RAWdescriptor_t UNIVERSAL_CHARSTRING_raw_
= {0,SG_NO
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,ORDER_LSB
,EXT_BIT_NO
,ORDER_LSB
,ORDER_LSB
,TOP_BIT_INHERITED
,0,0,0,8,0,NULL
,-1};