Merge pull request #78 from balaskoa/master
[deliverable/titan.core.git] / core / Encdec.cc
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 * Feher, Csaba
12 * Forstner, Matyas
13 * Ormandi, Matyas
14 * Raduly, Csaba
15 * Szabados, Kristof
16 * Szabo, Janos Zoltan – initial implementation
17 * Szalai, Gabor
18 * Zalanyi, Balazs Andor
19 *
20 ******************************************************************************/
21 #include "Encdec.hh"
22
23 #include "../common/memory.h"
24 #include "Octetstring.hh"
25 #include "Charstring.hh"
26 #include "String_struct.hh"
27 #include "RAW.hh"
28 #include "Error.hh"
29 #include "Logger.hh"
30
31 const TTCN_EncDec::error_behavior_t
32 TTCN_EncDec::default_error_behavior[TTCN_EncDec::ET_ALL] = {
33 TTCN_EncDec::EB_ERROR,
34 TTCN_EncDec::EB_ERROR,
35 TTCN_EncDec::EB_ERROR,
36 TTCN_EncDec::EB_WARNING,
37 TTCN_EncDec::EB_ERROR,
38 TTCN_EncDec::EB_WARNING,
39 TTCN_EncDec::EB_ERROR,
40 TTCN_EncDec::EB_WARNING,
41 TTCN_EncDec::EB_WARNING,
42 TTCN_EncDec::EB_ERROR,
43 TTCN_EncDec::EB_ERROR,
44 TTCN_EncDec::EB_ERROR,
45 TTCN_EncDec::EB_ERROR,
46 TTCN_EncDec::EB_ERROR,
47 TTCN_EncDec::EB_WARNING,
48 TTCN_EncDec::EB_WARNING,
49 TTCN_EncDec::EB_WARNING,
50 TTCN_EncDec::EB_ERROR,
51 TTCN_EncDec::EB_ERROR,
52 TTCN_EncDec::EB_ERROR,
53 TTCN_EncDec::EB_ERROR,
54 TTCN_EncDec::EB_IGNORE,
55 TTCN_EncDec::EB_WARNING,
56 TTCN_EncDec::EB_ERROR,
57 TTCN_EncDec::EB_ERROR
58 };
59
60 TTCN_EncDec::error_behavior_t
61 TTCN_EncDec::error_behavior[TTCN_EncDec::ET_ALL] = {
62 TTCN_EncDec::EB_ERROR,
63 TTCN_EncDec::EB_ERROR,
64 TTCN_EncDec::EB_ERROR,
65 TTCN_EncDec::EB_WARNING,
66 TTCN_EncDec::EB_ERROR,
67 TTCN_EncDec::EB_WARNING,
68 TTCN_EncDec::EB_ERROR,
69 TTCN_EncDec::EB_WARNING,
70 TTCN_EncDec::EB_WARNING,
71 TTCN_EncDec::EB_ERROR,
72 TTCN_EncDec::EB_ERROR,
73 TTCN_EncDec::EB_ERROR,
74 TTCN_EncDec::EB_ERROR,
75 TTCN_EncDec::EB_ERROR,
76 TTCN_EncDec::EB_WARNING,
77 TTCN_EncDec::EB_WARNING,
78 TTCN_EncDec::EB_WARNING,
79 TTCN_EncDec::EB_ERROR,
80 TTCN_EncDec::EB_ERROR,
81 TTCN_EncDec::EB_ERROR,
82 TTCN_EncDec::EB_ERROR,
83 TTCN_EncDec::EB_IGNORE,
84 TTCN_EncDec::EB_WARNING,
85 TTCN_EncDec::EB_ERROR,
86 TTCN_EncDec::EB_ERROR
87 };
88
89 TTCN_EncDec::error_type_t TTCN_EncDec::last_error_type=ET_NONE;
90 char *TTCN_EncDec::error_str=NULL;
91
92 static TTCN_EncDec::error_type_t& operator++(TTCN_EncDec::error_type_t& eb)
93 {
94 return eb
95 =(eb==TTCN_EncDec::ET_NONE)
96 ?TTCN_EncDec::ET_UNDEF
97 :TTCN_EncDec::error_type_t(eb+1);
98 }
99
100 void TTCN_EncDec::set_error_behavior(error_type_t p_et, error_behavior_t p_eb)
101 {
102 if(p_et<ET_UNDEF || p_et>ET_ALL || p_eb<EB_DEFAULT || p_eb>EB_IGNORE)
103 TTCN_error("EncDec::set_error_behavior(): Invalid parameter.");
104 if(p_eb==EB_DEFAULT) {
105 if(p_et==ET_ALL)
106 for(error_type_t i=ET_UNDEF; i<ET_ALL; ++i)
107 error_behavior[i]=default_error_behavior[i];
108 else
109 error_behavior[p_et]=default_error_behavior[p_et];
110 }
111 else {
112 if(p_et==ET_ALL)
113 for(error_type_t i=ET_UNDEF; i<ET_ALL; ++i)
114 error_behavior[i]=p_eb;
115 else
116 error_behavior[p_et]=p_eb;
117 }
118 }
119
120 TTCN_EncDec::error_behavior_t
121 TTCN_EncDec::get_error_behavior(error_type_t p_et)
122 {
123 if(p_et<ET_UNDEF || p_et>=ET_ALL)
124 TTCN_error("EncDec::get_error_behavior(): Invalid parameter.");
125 return error_behavior[p_et];
126 }
127
128 TTCN_EncDec::error_behavior_t
129 TTCN_EncDec::get_default_error_behavior(error_type_t p_et)
130 {
131 if(p_et<ET_UNDEF || p_et>=ET_ALL)
132 TTCN_error("EncDec::get_error_behavior(): Invalid parameter.");
133 return default_error_behavior[p_et];
134 }
135
136 void TTCN_EncDec::clear_error()
137 {
138 last_error_type=ET_NONE;
139 Free(error_str); error_str=NULL;
140 }
141
142 void TTCN_EncDec::error(error_type_t p_et, char *msg)
143 {
144 last_error_type=p_et;
145 Free(error_str);
146 error_str=msg;
147 if (p_et >= ET_UNDEF && p_et < ET_ALL) {
148 switch(error_behavior[p_et]) {
149 case TTCN_EncDec::EB_ERROR:
150 TTCN_error("%s", error_str);
151 case TTCN_EncDec::EB_WARNING:
152 TTCN_warning("%s", error_str);
153 break;
154 default:
155 break;
156 } // switch
157 }
158 }
159
160 TTCN_EncDec_ErrorContext *TTCN_EncDec_ErrorContext::head=NULL;
161 TTCN_EncDec_ErrorContext *TTCN_EncDec_ErrorContext::tail=NULL;
162
163 TTCN_EncDec_ErrorContext::TTCN_EncDec_ErrorContext()
164 {
165 msg=NULL;
166 if(!head) head=this;
167 if(tail) tail->next=this;
168 prev=tail;
169 next=0;
170 tail=this;
171 }
172
173 TTCN_EncDec_ErrorContext::TTCN_EncDec_ErrorContext(const char *fmt, ...)
174 {
175 va_list args;
176 va_start(args, fmt);
177 msg=mprintf_va_list(fmt, args);
178 va_end(args);
179 if(!head) head=this;
180 if(tail) tail->next=this;
181 prev=tail;
182 next=0;
183 tail=this;
184 }
185
186 TTCN_EncDec_ErrorContext::~TTCN_EncDec_ErrorContext()
187 {
188 Free(msg);
189 if(tail!=this)
190 TTCN_error("Internal error:"
191 " TTCN_EncDec_ErrorContext::~TTCN_EncDec_ErrorContext()");
192 if(prev) prev->next=NULL;
193 else head=NULL;
194 tail=prev;
195 }
196
197 void TTCN_EncDec_ErrorContext::set_msg(const char *fmt, ...)
198 {
199 Free(msg);
200 va_list args;
201 va_start(args, fmt);
202 msg=mprintf_va_list(fmt, args);
203 va_end(args);
204 }
205
206 void TTCN_EncDec_ErrorContext::error(TTCN_EncDec::error_type_t p_et,
207 const char *fmt, ...)
208 {
209 char *err_msg=NULL;
210 for(TTCN_EncDec_ErrorContext *p=head; p!=NULL; p=p->next)
211 err_msg=mputstr(err_msg, p->msg);
212 va_list parameters;
213 va_start(parameters, fmt);
214 err_msg=mputprintf_va_list(err_msg, fmt, parameters);
215 va_end(parameters);
216 TTCN_EncDec::error(p_et, err_msg);
217 }
218
219 void TTCN_EncDec_ErrorContext::error_internal(const char *fmt, ...)
220 {
221 char *err_msg=mcopystr("Internal error: ");
222 for(TTCN_EncDec_ErrorContext *p=head; p!=NULL; p=p->next)
223 err_msg=mputstr(err_msg, p->msg);
224 va_list parameters;
225 va_start(parameters, fmt);
226 err_msg=mputprintf_va_list(err_msg, fmt, parameters);
227 va_end(parameters);
228 TTCN_EncDec::error(TTCN_EncDec::ET_INTERNAL, err_msg);
229 TTCN_error("%s", TTCN_EncDec::get_error_str());
230 }
231
232 void TTCN_EncDec_ErrorContext::warning(const char *fmt, ...)
233 {
234 char *warn_msg=NULL;
235 for(TTCN_EncDec_ErrorContext *p=head; p!=NULL; p=p->next)
236 warn_msg=mputstr(warn_msg, p->msg);
237 va_list parameters;
238 va_start(parameters, fmt);
239 warn_msg=mputprintf_va_list(warn_msg, fmt, parameters);
240 va_end(parameters);
241 TTCN_warning("%s", warn_msg);
242 Free(warn_msg);
243 }
244
245 #define INITIAL_SIZE 1024
246 #define MEMORY_SIZE(n) (sizeof(buffer_struct) - sizeof(int) + (n))
247
248 void TTCN_Buffer::reset_buffer()
249 {
250 buf_pos = 0;
251 bit_pos = 0;
252 last_bit_pos = 0;
253 last_bit_bitpos = 0;
254 start_of_ext_bit = 0;
255 last_bit = FALSE;
256 current_bitorder = FALSE;
257 ext_bit_reverse = FALSE;
258 ext_level = 0;
259 }
260
261 void TTCN_Buffer::release_memory()
262 {
263 if (buf_ptr != NULL) {
264 if (buf_ptr->ref_count > 1) buf_ptr->ref_count--;
265 else if (buf_ptr->ref_count == 1) Free(buf_ptr);
266 else {
267 TTCN_EncDec_ErrorContext::error_internal("Invalid reference counter %u "
268 "when freeing a TTCN_Buffer.", buf_ptr->ref_count);
269 }
270 }
271 }
272
273 size_t TTCN_Buffer::get_memory_size(size_t target_size)
274 {
275 size_t new_size = INITIAL_SIZE;
276 while (new_size < target_size) {
277 size_t next_size = new_size + new_size;
278 if (next_size > new_size) new_size = next_size;
279 else {
280 // integer overflow occurred
281 return static_cast<size_t>(-1);
282 }
283 }
284 return new_size;
285 }
286
287 void TTCN_Buffer::copy_memory()
288 {
289 if (buf_ptr != NULL && buf_ptr->ref_count > 1) {
290 buffer_struct *old_ptr = buf_ptr;
291 old_ptr->ref_count--;
292 buf_size = get_memory_size(buf_len);
293 buf_ptr = (buffer_struct*)Malloc(MEMORY_SIZE(buf_size));
294 buf_ptr->ref_count = 1;
295 memcpy(buf_ptr->data_ptr, old_ptr->data_ptr, buf_len);
296 }
297 }
298
299 void TTCN_Buffer::increase_size(size_t size_incr)
300 {
301 if (buf_ptr != NULL) {
302 size_t target_size = buf_len + size_incr;
303 if (target_size < buf_len)
304 TTCN_EncDec_ErrorContext::error_internal("TTCN_Buffer: Overflow error "
305 "(cannot increase buffer size)."); // unsigned overflow
306 if (buf_ptr->ref_count > 1) { // shared, need to split (copy-on-write)
307 buffer_struct *old_ptr = buf_ptr;
308 old_ptr->ref_count--;
309 buf_size = get_memory_size(target_size);
310 buf_ptr = (buffer_struct*)Malloc(MEMORY_SIZE(buf_size));
311 #ifndef NDEBUG
312 memset(buf_ptr->data_ptr,0, buf_size);
313 #endif
314 buf_ptr->ref_count = 1;
315 memcpy(buf_ptr->data_ptr, old_ptr->data_ptr, buf_len);
316 } else if (target_size > buf_size) { // not shared, just change the size
317 buf_size = get_memory_size(target_size);
318 buf_ptr = (buffer_struct*)Realloc(buf_ptr, MEMORY_SIZE(buf_size));
319 #ifndef NDEBUG
320 memset(buf_ptr->data_ptr + buf_len,0, buf_size - buf_len);
321 #endif
322 }
323 } else { // a brand new buffer
324 buf_size = get_memory_size(size_incr);
325 buf_ptr = (buffer_struct*)Malloc(MEMORY_SIZE(buf_size));
326 #ifndef NDEBUG
327 memset(buf_ptr->data_ptr,0, buf_size);
328 #endif
329 buf_ptr->ref_count = 1;
330 }
331 }
332
333 TTCN_Buffer::TTCN_Buffer()
334 {
335 buf_ptr = NULL;
336 buf_size = 0;
337 buf_len = 0;
338 reset_buffer();
339 }
340
341 TTCN_Buffer::TTCN_Buffer(const TTCN_Buffer& p_buf)
342 {
343 buf_ptr = p_buf.buf_ptr;
344 buf_ptr->ref_count++;
345 buf_size = p_buf.buf_size;
346 buf_len = p_buf.buf_len;
347 reset_buffer();
348 }
349
350 TTCN_Buffer::TTCN_Buffer(const OCTETSTRING& p_os)
351 {
352 p_os.must_bound("Initializing a TTCN_Buffer with an unbound octetstring "
353 "value.");
354 buf_ptr = (buffer_struct*)p_os.val_ptr;
355 buf_ptr->ref_count++;
356 buf_size = p_os.val_ptr->n_octets;
357 buf_len = p_os.val_ptr->n_octets;
358 reset_buffer();
359 }
360
361 TTCN_Buffer::TTCN_Buffer(const CHARSTRING& p_cs)
362 {
363 p_cs.must_bound("Initializing a TTCN_Buffer with an unbound charstring "
364 "value.");
365 buf_ptr = (buffer_struct*)p_cs.val_ptr;
366 buf_ptr->ref_count++;
367 buf_size = p_cs.val_ptr->n_chars + 1;
368 buf_len = p_cs.val_ptr->n_chars;
369 reset_buffer();
370 }
371
372 TTCN_Buffer& TTCN_Buffer::operator=(const TTCN_Buffer& p_buf)
373 {
374 if (&p_buf != this) {
375 release_memory();
376 buf_ptr = p_buf.buf_ptr;
377 buf_ptr->ref_count++;
378 buf_size = p_buf.buf_size;
379 buf_len = p_buf.buf_len;
380 }
381 reset_buffer();
382 return *this;
383 }
384
385 TTCN_Buffer& TTCN_Buffer::operator=(const OCTETSTRING& p_os)
386 {
387 p_os.must_bound("Assignment of an unbound octetstring value to a "
388 "TTCN_Buffer.");
389 release_memory();
390 buf_ptr = (buffer_struct*)p_os.val_ptr;
391 buf_ptr->ref_count++;
392 buf_size = p_os.val_ptr->n_octets;
393 buf_len = p_os.val_ptr->n_octets;
394 reset_buffer();
395 return *this;
396 }
397
398 TTCN_Buffer& TTCN_Buffer::operator=(const CHARSTRING& p_cs)
399 {
400 p_cs.must_bound("Assignment of an unbound charstring value to a "
401 "TTCN_Buffer.");
402 release_memory();
403 buf_ptr = (buffer_struct*)p_cs.val_ptr;
404 buf_ptr->ref_count++;
405 buf_size = p_cs.val_ptr->n_chars + 1;
406 buf_len = p_cs.val_ptr->n_chars;
407 reset_buffer();
408 return *this;
409 }
410
411 void TTCN_Buffer::clear()
412 {
413 release_memory();
414 buf_ptr = NULL;
415 buf_size = 0;
416 buf_len = 0;
417 reset_buffer();
418 }
419
420 const unsigned char* TTCN_Buffer::get_data() const
421 {
422 if (buf_ptr != NULL) return buf_ptr->data_ptr;
423 else return NULL;
424 }
425
426 const unsigned char* TTCN_Buffer::get_read_data() const
427 {
428 if (buf_ptr != NULL) return buf_ptr->data_ptr + buf_pos;
429 else return NULL;
430 }
431
432 void TTCN_Buffer::set_pos(size_t new_pos)
433 {
434 if (new_pos < buf_len) buf_pos = new_pos;
435 else buf_pos = buf_len;
436 }
437
438 void TTCN_Buffer::increase_pos(size_t delta)
439 {
440 size_t new_buf_pos=buf_pos+delta;
441 if(new_buf_pos<buf_pos || new_buf_pos>buf_len)
442 buf_pos=buf_len;
443 else
444 buf_pos=new_buf_pos;
445 }
446
447 void TTCN_Buffer::get_end(unsigned char*& end_ptr, size_t& end_len)
448 {
449 increase_size(end_len);
450 end_len = buf_size - buf_len;
451 if (buf_ptr != NULL) end_ptr = buf_ptr->data_ptr + buf_len;
452 else end_ptr = NULL;
453 }
454
455 void TTCN_Buffer::increase_length(size_t size_incr)
456 {
457 if (buf_size < buf_len + size_incr) increase_size(size_incr);
458 buf_len += size_incr;
459 }
460
461 void TTCN_Buffer::put_c(unsigned char c)
462 {
463 increase_size(1);
464 buf_ptr->data_ptr[buf_len] = c;
465 buf_len++;
466 }
467
468 void TTCN_Buffer::put_s(size_t len, const unsigned char *s)
469 {
470 if (len > 0) {
471 increase_size(len);
472 memcpy(buf_ptr->data_ptr + buf_len, s, len);
473 buf_len += len;
474 }
475 }
476
477 void TTCN_Buffer::put_string(const OCTETSTRING& p_os)
478 {
479 p_os.must_bound("Appending an unbound octetstring value to a TTCN_Buffer.");
480 if (p_os.val_ptr->n_octets > 0) {
481 if (buf_len > 0) {
482 increase_size(p_os.val_ptr->n_octets);
483 memcpy(buf_ptr->data_ptr + buf_len, p_os.val_ptr->octets_ptr,
484 p_os.val_ptr->n_octets);
485 buf_len += p_os.val_ptr->n_octets;
486 } else {
487 release_memory();
488 buf_ptr = (buffer_struct*)p_os.val_ptr;
489 buf_ptr->ref_count++;
490 buf_size = p_os.val_ptr->n_octets;
491 buf_len = p_os.val_ptr->n_octets;
492 }
493 }
494 }
495
496 void TTCN_Buffer::put_string(const CHARSTRING& p_cs)
497 {
498 p_cs.must_bound("Appending an unbound charstring value to a TTCN_Buffer.");
499 if (p_cs.val_ptr->n_chars > 0) { // there is something in the CHARSTRING
500 if (buf_len > 0) { // there is something in this buffer, append
501 increase_size(p_cs.val_ptr->n_chars);
502 memcpy(buf_ptr->data_ptr + buf_len, p_cs.val_ptr->chars_ptr,
503 p_cs.val_ptr->n_chars);
504 buf_len += p_cs.val_ptr->n_chars;
505 } else { // share the data
506 release_memory();
507 buf_ptr = (buffer_struct*)p_cs.val_ptr;
508 buf_ptr->ref_count++;
509 buf_size = p_cs.val_ptr->n_chars + 1;
510 buf_len = p_cs.val_ptr->n_chars;
511 }
512 }
513 }
514
515 void TTCN_Buffer::put_buf(const TTCN_Buffer& p_buf) {
516 if (p_buf.buf_ptr == 0) return;
517 if (p_buf.buf_len > 0) { // there is something in the other buffer
518 if (buf_len > 0) { // there is something in this buffer, append
519 increase_size(p_buf.buf_len);
520 memcpy(buf_ptr->data_ptr + buf_len, p_buf.buf_ptr->data_ptr,
521 p_buf.buf_len);
522 buf_len += p_buf.buf_len;
523 }
524 else { // share the data
525 *this = p_buf;
526 }
527 }
528 }
529
530 void TTCN_Buffer::get_string(OCTETSTRING& p_os)
531 {
532 p_os.clean_up();
533 if (buf_len > 0) {
534 if (buf_ptr->ref_count > 1) {
535 p_os.init_struct(buf_len);
536 memcpy(p_os.val_ptr->octets_ptr, buf_ptr->data_ptr, buf_len);
537 } else {
538 if (buf_size != buf_len) {
539 buf_ptr = (buffer_struct*)Realloc(buf_ptr, MEMORY_SIZE(buf_len));
540 buf_size = buf_len;
541 }
542 p_os.val_ptr = (OCTETSTRING::octetstring_struct*)buf_ptr;
543 p_os.val_ptr->ref_count++;
544 p_os.val_ptr->n_octets = buf_len;
545 }
546 } else p_os.init_struct(0);
547 }
548
549 void TTCN_Buffer::get_string(CHARSTRING& p_cs)
550 {
551 p_cs.clean_up();
552 if (buf_len > 0) {
553 if (buf_ptr->ref_count > 1) { // buffer is shared, copy is needed
554 p_cs.init_struct(buf_len);
555 memcpy(p_cs.val_ptr->chars_ptr, buf_ptr->data_ptr, buf_len);
556 } else { // we are the sole owner
557 // Share our buffer_struct with CHARSTRING's charstring_struct
558 // (they have the same layout), after putting in a string terminator.
559 if (buf_size != buf_len + 1) {
560 buf_ptr = (buffer_struct*)Realloc(buf_ptr, MEMORY_SIZE(buf_len + 1));
561 buf_size = buf_len + 1;
562 }
563 p_cs.val_ptr = (CHARSTRING::charstring_struct*)buf_ptr;
564 p_cs.val_ptr->ref_count++;
565 p_cs.val_ptr->n_chars = buf_len;
566 p_cs.val_ptr->chars_ptr[buf_len] = '\0';
567 }
568 } else p_cs.init_struct(0);
569 }
570
571 void TTCN_Buffer::get_string(UNIVERSAL_CHARSTRING& p_cs)
572 {
573 p_cs.clean_up();
574 if (buf_len > 0) {
575 // TODO what if not multiple of 4 ?
576 p_cs.init_struct(buf_len / 4);
577 memcpy(p_cs.val_ptr->uchars_ptr, buf_ptr->data_ptr, buf_len);
578 } else p_cs.init_struct(0);
579 }
580
581 void TTCN_Buffer::cut()
582 {
583 if (buf_pos > 0) {
584 if (buf_pos > buf_len)
585 TTCN_EncDec_ErrorContext::error_internal("Read pointer points beyond "
586 "the buffer end when cutting from a TTCN_Buffer.");
587 size_t new_len = buf_len - buf_pos;
588 if (new_len > 0) {
589 if (buf_ptr->ref_count > 1) {
590 buffer_struct *old_ptr = buf_ptr;
591 old_ptr->ref_count--;
592 buf_size = get_memory_size(new_len);
593 buf_ptr = (buffer_struct*)Malloc(MEMORY_SIZE(buf_size));
594 buf_ptr->ref_count = 1;
595 memcpy(buf_ptr->data_ptr, old_ptr->data_ptr + buf_pos, new_len);
596 } else {
597 memmove(buf_ptr->data_ptr, buf_ptr->data_ptr + buf_pos, new_len);
598 size_t new_size = get_memory_size(new_len);
599 if (new_size < buf_size) {
600 buf_ptr = (buffer_struct*)Realloc(buf_ptr, MEMORY_SIZE(new_size));
601 buf_size = new_size;
602 }
603 }
604 } else {
605 release_memory();
606 buf_ptr = NULL;
607 buf_size = 0;
608 }
609 buf_len = new_len;
610 }
611 reset_buffer();
612 }
613
614 void TTCN_Buffer::cut_end()
615 {
616 if (buf_pos > buf_len)
617 TTCN_EncDec_ErrorContext::error_internal("Read pointer points beyond "
618 "the buffer end when cutting from a TTCN_Buffer.");
619 if (buf_pos < buf_len) {
620 if (buf_pos > 0) {
621 if (buf_ptr == NULL)
622 TTCN_EncDec_ErrorContext::error_internal("Data pointer is NULL when "
623 "cutting from a TTCN_Buffer.");
624 if (buf_ptr->ref_count == 1) {
625 size_t new_size = get_memory_size(buf_pos);
626 if (new_size < buf_size) {
627 buf_ptr = (buffer_struct*)Realloc(buf_ptr, MEMORY_SIZE(new_size));
628 buf_size = new_size;
629 }
630 }
631 } else {
632 release_memory();
633 buf_ptr = NULL;
634 buf_size = 0;
635 }
636 buf_len = buf_pos;
637 }
638 last_bit_pos = 0;
639 last_bit_bitpos = 0;
640 start_of_ext_bit = 0;
641 last_bit = FALSE;
642 current_bitorder = FALSE;
643 ext_bit_reverse = FALSE;
644 ext_level = 0;
645 }
646
647 boolean TTCN_Buffer::contains_complete_TLV()
648 {
649 if (buf_len > buf_pos) {
650 ASN_BER_TLV_t tmp_tlv;
651 return ASN_BER_str2TLV(buf_len - buf_pos, buf_ptr->data_ptr + buf_pos,
652 tmp_tlv, BER_ACCEPT_ALL);
653 } else return FALSE;
654 }
655
656 void TTCN_Buffer::log() const
657 {
658 TTCN_Logger::log_event("Buffer: size: %lu, pos: %lu, len: %lu data: (",
659 (unsigned long)buf_size, (unsigned long)buf_pos, (unsigned long)buf_len);
660 if (buf_len > 0) {
661 const unsigned char *data_ptr = buf_ptr->data_ptr;
662 for(size_t i=0; i<buf_pos; i++)
663 TTCN_Logger::log_octet(data_ptr[i]);
664 TTCN_Logger::log_event_str(" | ");
665 for(size_t i=buf_pos; i<buf_len; i++)
666 TTCN_Logger::log_octet(data_ptr[i]);
667 }
668 TTCN_Logger::log_char(')');
669 }
670
671 void TTCN_Buffer::put_b(size_t len, const unsigned char *s,
672 const RAW_coding_par& coding_par, int align)
673 {
674
675 unsigned char* st=NULL;
676 unsigned char* st2=NULL;
677 int loc_align=align<0?-align:align;
678 bool must_align=false;
679 raw_order_t local_bitorder=coding_par.bitorder;
680 raw_order_t local_fieldorder=coding_par.fieldorder;
681 if(current_bitorder) {
682 if(local_bitorder==ORDER_LSB) local_bitorder=ORDER_MSB;
683 else local_bitorder=ORDER_LSB;
684 if(local_fieldorder==ORDER_LSB) local_fieldorder=ORDER_MSB;
685 else local_fieldorder=ORDER_LSB;
686 }
687 /*printf("len:%d\r\n",len);
688 printf("align:%d\r\n",align);
689 printf("coding bito:%s,byte:%s,field:%s\r\n",coding_par.bitorder==ORDER_MSB?"M":"L",
690 coding_par.byteorder==ORDER_MSB?"M":"L",
691 coding_par.fieldorder==ORDER_MSB?"M":"L"
692 );
693 printf("local bito:%s,field:%s\r\n",local_bitorder==ORDER_MSB?"M":"L",
694 local_fieldorder==ORDER_MSB?"M":"L"
695 );*/
696 if(align) {
697 if((local_fieldorder==ORDER_LSB && (local_bitorder!=coding_par.byteorder))||
698 (local_fieldorder==ORDER_MSB && (local_bitorder==coding_par.byteorder))) {
699 st=(unsigned char*)Malloc((len+loc_align+7)/8*sizeof(unsigned char));
700 memset(st,0,(len+loc_align+7)/8*sizeof(unsigned char));
701 if(align>0){
702 memcpy(st,s,(len+7)/8*sizeof(unsigned char));
703 if(len%8) st[(len+7)/8-1]&=BitMaskTable[len%8];
704 }
705 else{
706 if(loc_align%8){
707 int bit_bound=loc_align%8;
708 size_t max_index=(len+loc_align+7)/8-loc_align/8-1;
709 unsigned char* ptr=st+loc_align/8;
710 unsigned char mask=BitMaskTable[bit_bound];
711 for(size_t a=0;a<(len+7)/8;a++){
712 ptr[a]&=mask;
713 ptr[a]|=s[a]<<(8-bit_bound);
714 if(a<max_index) ptr[a+1]=s[a]>>bit_bound;
715 }
716 }
717 else{
718 memcpy(st+loc_align/8,s,(len+7)/8*sizeof(unsigned char));
719 }
720 }
721 s=st;
722 len+=loc_align;
723 }
724 else{
725 if(coding_par.byteorder==ORDER_MSB) align=-align;
726 if(align<0) put_zero(loc_align,local_fieldorder);
727 else must_align=true;
728 }
729 }
730 if(len==0) {
731 if(must_align) put_zero(loc_align,local_fieldorder);
732 return;
733 }
734 size_t new_size=((bit_pos==0?buf_len*8:buf_len*8-(8-bit_pos))+len+7)/8;
735 size_t new_bit_pos=(bit_pos+len)%8;
736 if (new_size > buf_len) increase_size(new_size - buf_len);
737 else copy_memory();
738 unsigned char *data_ptr = buf_ptr != NULL ? buf_ptr->data_ptr : NULL;
739 //printf("buf_len:%d bit_pos:%d\r\n",buf_len,bit_pos);
740 //printf("new_size:%d new_bit_pos:%d\r\n",new_size,new_bit_pos);
741 if(coding_par.hexorder==ORDER_MSB){
742 st2=(unsigned char*)Malloc((len+7)/8*sizeof(unsigned char));
743 if(bit_pos==4){
744 st2[0]=s[0];
745 for(size_t a=1;a<(len+7)/8;a++){
746 unsigned char ch='\0';
747 ch|=s[a-1]>>4;
748 st2[a-1]=(st2[a-1]&0x0f)|(s[a]<<4);
749 st2[a]=(s[a]&0xf0)|ch;
750 }
751 }
752 else{
753 for(size_t a=0;a<(len+7)/8;a++) st2[a]=(s[a]<<4)|(s[a]>>4);
754 if(len%8) st2[(len+7)/8]>>=4;
755 }
756 s=st2;
757 }
758 if(bit_pos+len<=8){ // there is enough space within 1 octet to store the data
759 if(local_bitorder==ORDER_LSB){
760 if(local_fieldorder==ORDER_LSB){
761 data_ptr[new_size-1]=
762 (data_ptr[new_size-1]&BitMaskTable[bit_pos])|
763 (s[0]<<bit_pos);
764 }else{
765 data_ptr[new_size-1]=
766 (data_ptr[new_size-1]&~BitMaskTable[8-bit_pos])|
767 ((s[0]&BitMaskTable[len])<<(8-bit_pos-len));
768 }
769 }
770 else{
771 if(local_fieldorder==ORDER_LSB){
772 data_ptr[new_size-1]=
773 (data_ptr[new_size-1]&BitMaskTable[bit_pos])|
774 (REVERSE_BITS(s[0])>>(8-len-bit_pos));
775 }else{
776 data_ptr[new_size-1]=
777 (data_ptr[new_size-1]&~BitMaskTable[8-bit_pos])|
778 (REVERSE_BITS(s[0]&BitMaskTable[len])>>bit_pos);
779 }
780 }
781 }
782 else if(bit_pos==0 && (len%8)==0){ // octet aligned data
783 if(coding_par.byteorder==ORDER_LSB){
784 if(local_bitorder==ORDER_LSB){
785 memcpy(data_ptr+buf_len, s, len/8);
786 }
787 else{
788 unsigned char *prt=data_ptr+buf_len;
789 for(size_t a=0;a<len/8;a++) prt[a]=REVERSE_BITS(s[a]);
790 }
791 }
792 else{
793 if(local_bitorder==ORDER_LSB){
794 unsigned char *prt=data_ptr+buf_len;
795 for(size_t a=0,b=len/8-1;a<len/8;a++,b--) prt[a]=s[b];
796 }
797 else{
798 unsigned char *prt=data_ptr+buf_len;
799 for(size_t a=0,b=len/8-1;a<len/8;a++,b--) prt[a]=REVERSE_BITS(s[b]);
800 }
801 }
802 }
803 else{
804 size_t maxindex=new_size-1;
805 if(coding_par.byteorder==ORDER_LSB){
806 if(local_bitorder==ORDER_LSB){
807 if(bit_pos){
808 unsigned char mask1=BitMaskTable[bit_pos];
809 unsigned char *prt=data_ptr+(buf_len==0?0:buf_len-1);
810 if(local_fieldorder==ORDER_MSB){
811 unsigned int num_bytes = (len+7) / 8;
812 unsigned int active_bits_in_last = len % 8;
813 if(!active_bits_in_last) active_bits_in_last=8;
814 for(unsigned int a=0; a < num_bytes; a++){
815 prt[a]&=REVERSE_BITS(mask1);
816 unsigned char sa = s[a];
817 if (a == num_bytes - 1) { // last byte
818 sa <<= (8 - active_bits_in_last);
819 // push bits up so the first active bit is in MSB
820 }
821 prt[a]|=(sa>>bit_pos)&~REVERSE_BITS(mask1);
822 if(a<maxindex)
823 prt[a+1]=sa<<(8-bit_pos);
824 }
825 }
826 else{
827 for(unsigned int a=0;a<(len+7)/8;a++){
828 prt[a]&=mask1;
829 prt[a]|=s[a]<<bit_pos;
830 if(a<maxindex)
831 prt[a+1]=s[a]>>(8-bit_pos);
832 }
833 }
834 }
835 else{ // start from octet boundary
836 memcpy(data_ptr+buf_len, s, (len+7)/8*sizeof(unsigned char));
837 if(local_fieldorder==ORDER_MSB && new_bit_pos){
838 data_ptr[new_size-1]<<=(8-new_bit_pos);
839
840 }
841 }
842 }
843 else{ // bitorder==ORDER_MSB
844 if(bit_pos){
845 unsigned char mask1=REVERSE_BITS(BitMaskTable[bit_pos]);
846 unsigned char *prt=data_ptr+(buf_len==0?0:buf_len-1);
847 if(local_fieldorder==ORDER_MSB){
848 prt[0]&=mask1;
849 prt[0]|=REVERSE_BITS(s[0])>>bit_pos;
850 prt[1]=REVERSE_BITS(s[0])<<(8-bit_pos);
851 }
852 else{
853 prt[0]&=REVERSE_BITS(mask1);
854 prt[0]|=REVERSE_BITS(s[0])&~REVERSE_BITS(mask1);
855 prt[1]=REVERSE_BITS(s[0])<<(8-bit_pos);
856 }
857 for(unsigned int a=1;a<(len+7)/8;a++){
858 prt[a]&=mask1;
859 prt[a]|=REVERSE_BITS(s[a])>>bit_pos;
860 if(a<maxindex)
861 prt[a+1]=REVERSE_BITS(s[a])<<(8-bit_pos);
862 }
863 }
864 else{ // start from octet boundary
865 unsigned char *prt=data_ptr+buf_len;
866 for(unsigned int a=0;a<(len+7)/8;a++) prt[a]=REVERSE_BITS(s[a]);
867 }
868 if(local_fieldorder==ORDER_LSB && new_bit_pos)
869 data_ptr[new_size-1]>>=(8-new_bit_pos);
870 }
871 }
872 else{ // byteorder==ORDER_MSB
873 if(local_bitorder==ORDER_LSB){
874 if(bit_pos){
875 unsigned char mask1=BitMaskTable[bit_pos];
876 unsigned char ch=get_byte_rev(s,len,0);
877 unsigned char *prt=data_ptr+(buf_len==0?0:buf_len-1);
878 if(local_fieldorder==ORDER_MSB){
879 prt[0]&=REVERSE_BITS(mask1);
880 prt[0]|=ch>>bit_pos;
881 prt[1]=ch<<(8-bit_pos);
882 }
883 else{
884 prt[0]&=mask1;
885 prt[0]|=ch&~mask1;
886 prt[1]=ch<<(8-bit_pos);
887 }
888 for(unsigned int a=1;a<(len+7)/8;a++){
889 ch=get_byte_rev(s,len,a);
890 prt[a]&=REVERSE_BITS(mask1);
891 prt[a]|=ch>>bit_pos;
892 if(a<maxindex)
893 prt[a+1]=ch<<(8-bit_pos);
894 }
895 }
896 else{
897 unsigned char *prt=data_ptr+buf_len;
898 for(unsigned int a=0;a<(len+7)/8;a++) prt[a]=get_byte_rev(s,len,a);
899 }
900 if(local_fieldorder==ORDER_LSB && new_bit_pos)
901 data_ptr[new_size-1]>>=(8-new_bit_pos);
902 }
903 else{ // bitorder==ORDER_MSB
904 if(bit_pos){
905 unsigned char mask1=BitMaskTable[bit_pos];
906 unsigned char ch=get_byte_rev(s,len,0);
907 unsigned char *prt=data_ptr+(buf_len==0?0:buf_len-1);
908 if(local_fieldorder==ORDER_MSB){
909 prt[0]&=REVERSE_BITS(mask1);
910 prt[0]|=REVERSE_BITS(ch)&~REVERSE_BITS(mask1);
911 prt[1]=REVERSE_BITS(ch)>>(8-bit_pos);
912 }
913 else{
914 prt[0]&=mask1;
915 prt[0]|=REVERSE_BITS(ch)<<bit_pos;
916 prt[1]=REVERSE_BITS(ch)>>(8-bit_pos);
917 }
918 for(unsigned int a=1;a<(len+7)/8;a++){
919 ch=get_byte_rev(s,len,a);
920 prt[a]&=mask1;
921 prt[a]|=REVERSE_BITS(ch)<<bit_pos;
922 if(a<maxindex)
923 prt[a+1]=REVERSE_BITS(ch)>>(8-bit_pos);
924 }
925 }
926 else{ // start from octet boundary
927 unsigned char *prt=data_ptr+buf_len;
928 for(unsigned int a=0;a<(len+7)/8;a++) prt[a]=
929 REVERSE_BITS(get_byte_rev(s,len,a));
930 }
931 if(local_fieldorder==ORDER_MSB && new_bit_pos)
932 data_ptr[new_size-1]<<=(8-new_bit_pos);
933 }
934 }
935 }
936 if(st) Free(st);
937 if(st2) Free(st2);
938 /* last_bit_pos=((bit_pos==0?buf_len*8:buf_len*8-(8-bit_pos))+len+6)/8;
939 if(local_fieldorder==ORDER_LSB)
940 last_bit_bitpos=(bit_pos+len-1)%8;
941 else
942 last_bit_bitpos=7-(bit_pos+len-1)%8;*/
943 buf_len=new_size;
944 bit_pos=new_bit_pos;
945 if(bit_pos){
946 last_bit_pos=buf_len-1;
947 if(local_fieldorder==ORDER_LSB)
948 last_bit_bitpos=bit_pos-1;
949 else
950 last_bit_bitpos=7-(bit_pos-1);
951 }
952 else{
953 last_bit_pos=buf_len-1;
954 if(local_fieldorder==ORDER_LSB)
955 last_bit_bitpos=7;
956 else
957 last_bit_bitpos=0;
958 }
959 if(must_align) put_zero(loc_align,local_fieldorder);
960 }
961
962 void TTCN_Buffer::get_b(size_t len, unsigned char *s,
963 const RAW_coding_par& coding_par, raw_order_t top_bit_order)
964 {
965 if(len==0) return;
966 size_t new_buf_pos=buf_pos+(bit_pos+len)/8;
967 size_t new_bit_pos=(bit_pos+len)%8;
968 raw_order_t local_bitorder=coding_par.bitorder;
969 raw_order_t local_fieldorder=coding_par.fieldorder;
970 if(top_bit_order==ORDER_LSB){
971 if(local_bitorder==ORDER_LSB) local_bitorder=ORDER_MSB;
972 else local_bitorder=ORDER_LSB;
973 if(local_fieldorder==ORDER_LSB) local_fieldorder=ORDER_MSB;
974 else local_fieldorder=ORDER_LSB;
975 }
976 const unsigned char *data_ptr = buf_ptr != NULL ? buf_ptr->data_ptr : NULL;
977 if(bit_pos+len<=8){ // the data is within 1 octet
978 if(local_bitorder==ORDER_LSB){
979 if(local_fieldorder==ORDER_LSB){
980 s[0]=data_ptr[buf_pos]>>bit_pos;
981 }else{
982 s[0]=data_ptr[buf_pos]>>(8-bit_pos-len);
983 }
984 }
985 else{
986 if(local_fieldorder==ORDER_LSB){
987 s[0]=REVERSE_BITS(data_ptr[buf_pos])>>(8-bit_pos-len);
988 }else{
989 s[0]=REVERSE_BITS(data_ptr[buf_pos])>>bit_pos;
990 }
991 }
992 }
993 else if(bit_pos==0 && (len%8)==0){ // octet aligned data
994 if(coding_par.byteorder==ORDER_LSB){
995 if(local_bitorder==ORDER_LSB){
996 memcpy(s, data_ptr+buf_pos, len/8*sizeof(unsigned char));
997 }
998 else{
999 const unsigned char *prt=data_ptr+buf_pos;
1000 for(size_t a=0;a<len/8;a++) s[a]=REVERSE_BITS(prt[a]);
1001 }
1002 }
1003 else{
1004 if(local_bitorder==ORDER_LSB){
1005 const unsigned char *prt=data_ptr+buf_pos;
1006 for(size_t a=0,b=len/8-1;a<len/8;a++,b--) s[a]=prt[b];
1007 }
1008 else{
1009 const unsigned char *prt=data_ptr+buf_pos;
1010 for(size_t a=0,b=len/8-1;a<len/8;a++,b--) s[a]=REVERSE_BITS(prt[b]);
1011 }
1012 }
1013 }
1014 else{ // unaligned
1015 size_t num_bytes = (len + 7) / 8;
1016 if(coding_par.byteorder==ORDER_LSB){
1017 if(local_bitorder==ORDER_LSB){
1018 if(bit_pos){
1019 unsigned char mask1=BitMaskTable[8-bit_pos];
1020 if(local_fieldorder==ORDER_LSB){
1021 for(unsigned int a=0;a<num_bytes;a++){
1022 s[a]=(get_byte_align(len,local_fieldorder,ORDER_MSB,a+1)
1023 <<(8-bit_pos))|
1024 ((get_byte_align(len,local_fieldorder,ORDER_MSB,a)
1025 >>bit_pos)&mask1);
1026 }
1027 } else {
1028 mask1=BitMaskTable[bit_pos];
1029 for(unsigned int a=0;a<num_bytes;a++){
1030 s[a]=(get_byte_align(len,local_fieldorder,ORDER_LSB,a+1)
1031 >>(8-bit_pos)&mask1)|
1032 ((get_byte_align(len,local_fieldorder,ORDER_LSB,a)
1033 <<bit_pos));
1034 }
1035 int active_bits_in_last_byte = len % 8;
1036 if (active_bits_in_last_byte) {
1037 s[num_bytes - 1] >>= (8 - active_bits_in_last_byte);
1038 }
1039 }
1040 }
1041 else{ // start from octet boundary
1042 memcpy(s, data_ptr+buf_pos, num_bytes*sizeof(unsigned char));
1043 if(local_fieldorder==ORDER_MSB && new_bit_pos)
1044 s[num_bytes-1]>>=(8-new_bit_pos);
1045 }
1046 }
1047 else{ // bitorder==ORDER_MSB
1048 if(bit_pos){
1049 unsigned char mask1=BitMaskTable[bit_pos];
1050 for(unsigned int a=0;a<num_bytes;a++){
1051 s[a]=REVERSE_BITS(
1052 ((get_byte_align(len,local_fieldorder,ORDER_LSB,a+1)
1053 >>(8-bit_pos))&mask1)|
1054 (get_byte_align(len,local_fieldorder,ORDER_LSB,a)
1055 <<bit_pos));
1056 }
1057 }
1058 else{ // start from octet boundary
1059 const unsigned char *prt=data_ptr+buf_pos;
1060 for(unsigned int a=0;a<num_bytes;a++) s[a]=REVERSE_BITS(prt[a]);
1061 if(local_fieldorder==ORDER_LSB && new_bit_pos)
1062 s[num_bytes-1]>>=(8-new_bit_pos);
1063 }
1064 }
1065 }
1066 else{ // byteorder==ORDER_MSB
1067 if(local_bitorder==ORDER_LSB){
1068 if(new_bit_pos){
1069 unsigned char mask1=BitMaskTable[new_bit_pos];
1070 for(unsigned int a=0,b=(bit_pos+len)/8;a<num_bytes;a++,b--){
1071 s[a]=((get_byte_align(len,local_fieldorder,ORDER_LSB,b)
1072 >>(8-new_bit_pos))&mask1)|
1073 (get_byte_align(len,local_fieldorder,ORDER_LSB,b-1)
1074 <<new_bit_pos);
1075 }
1076 }
1077 else{
1078 // unsigned char *prt=data_ptr+buf_pos;
1079 for(unsigned int a=0,b=new_buf_pos-1;a<num_bytes;a++,b--)
1080 s[a]=data_ptr[b];
1081 if(local_fieldorder==ORDER_LSB && bit_pos)
1082 s[num_bytes-1]>>=bit_pos;
1083 }
1084 }
1085 else{ // bitorder==ORDER_MSB
1086 if(new_bit_pos){
1087 // unsigned char mask1=BitMaskTable[new_bit_pos];
1088 for(unsigned int a=0,b=(bit_pos+len)/8;a<num_bytes;a++,b--){
1089 s[a]=REVERSE_BITS(
1090 (get_byte_align(len,local_fieldorder,ORDER_MSB,b)
1091 <<(8-new_bit_pos))|
1092 (get_byte_align(len,local_fieldorder,ORDER_MSB,b-1)
1093 >>new_bit_pos));
1094 }
1095 }
1096 else{ // start from octet boundary
1097 // unsigned char *prt=data_ptr+buf_pos;
1098 for(unsigned int a=0,b=new_buf_pos-1;a<num_bytes;a++,b--)
1099 s[a]=REVERSE_BITS(data_ptr[b]);
1100 if(local_fieldorder==ORDER_MSB && bit_pos)
1101 s[num_bytes-1]>>=bit_pos;
1102 }
1103 }
1104 }
1105 }
1106 if(coding_par.hexorder==ORDER_MSB){
1107 if(bit_pos==4){
1108 for(size_t a=1;a<(len+7)/8;a++){
1109 unsigned char ch='\0';
1110 ch|=s[a-1]>>4;
1111 s[a-1]=(s[a-1]&0x0f)|(s[a]<<4);
1112 s[a]=(s[a]&0xf0)|ch;
1113 }
1114 }
1115 else{
1116 for(size_t a=0;a<(len+7)/8;a++) s[a]=(s[a]<<4)|(s[a]>>4);
1117 if(len%8) s[(len+7)/8]>>=4;
1118 }
1119 }
1120
1121 size_t last_bit_offset = bit_pos + len - 1;
1122 unsigned char last_bit_octet = data_ptr[buf_pos + last_bit_offset / 8];
1123 if (local_fieldorder == ORDER_LSB) last_bit_octet >>= last_bit_offset % 8;
1124 else last_bit_octet >>= 7 - last_bit_offset % 8;
1125 if (last_bit_octet & 0x01) last_bit = TRUE;
1126 else last_bit = FALSE;
1127
1128 buf_pos=new_buf_pos;
1129 bit_pos=new_bit_pos;
1130 }
1131
1132 void TTCN_Buffer::put_zero(size_t len, raw_order_t fieldorder)
1133 {
1134 if(len==0) return;
1135 size_t new_size=((bit_pos==0?buf_len*8:buf_len*8-(8-bit_pos))+len+7)/8;
1136 if (new_size > buf_len) increase_size(new_size - buf_len);
1137 else copy_memory();
1138 unsigned char *data_ptr = buf_ptr != NULL ? buf_ptr->data_ptr : NULL;
1139 if(bit_pos){
1140 if(bit_pos+len>8){
1141 unsigned char mask1=BitMaskTable[bit_pos];
1142 unsigned char *prt=data_ptr+(buf_len==0?0:buf_len-1);
1143 if(fieldorder==ORDER_LSB) prt[0]&=mask1;
1144 else prt[0]&=~mask1;
1145 memset(prt+1, 0, (len-1+bit_pos)/8);
1146 }
1147 else {
1148 if(fieldorder==ORDER_LSB)
1149 data_ptr[new_size-1]=data_ptr[new_size-1]&BitMaskTable[bit_pos];
1150 else
1151 data_ptr[new_size-1]=data_ptr[new_size-1]&
1152 REVERSE_BITS(BitMaskTable[bit_pos]);
1153 }
1154 }
1155 else {
1156 memset(data_ptr+buf_len, 0, (len+7)/8);
1157 }
1158 buf_len=new_size;
1159 bit_pos=(bit_pos+len)%8;
1160 if(bit_pos){
1161 last_bit_pos=buf_len-1;
1162 if(fieldorder==ORDER_LSB)
1163 last_bit_bitpos=bit_pos-1;
1164 else
1165 last_bit_bitpos=7-(bit_pos-1);
1166 }
1167 else{
1168 last_bit_pos=buf_len-1;
1169 if(fieldorder==ORDER_LSB)
1170 last_bit_bitpos=7;
1171 else
1172 last_bit_bitpos=0;
1173 }
1174 }
1175
1176 const unsigned char* TTCN_Buffer::get_read_data(size_t &bitpos) const
1177 {
1178 bitpos=bit_pos;
1179 if (buf_ptr != NULL) return buf_ptr->data_ptr + buf_pos;
1180 else return NULL;
1181 }
1182
1183 void TTCN_Buffer::set_pos(size_t pos, size_t bitpos)
1184 {
1185 buf_pos=pos<buf_len?pos:buf_len;
1186 bit_pos=bitpos;
1187 }
1188
1189
1190 void TTCN_Buffer::set_pos_bit(size_t new_bit_pos)
1191 {
1192 size_t new_pos = new_bit_pos / 8;
1193 if (new_pos < buf_len) {
1194 buf_pos = new_pos;
1195 bit_pos = new_bit_pos % 8;
1196 } else {
1197 buf_pos = buf_len;
1198 bit_pos = 0;
1199 }
1200 }
1201
1202 void TTCN_Buffer::increase_pos_bit(size_t delta)
1203 {
1204 size_t new_buf_pos=buf_pos+(bit_pos+delta)/8; // bytes
1205 if(new_buf_pos<buf_pos || new_buf_pos>buf_len) {
1206 buf_pos=buf_len;
1207 bit_pos=7;
1208 }
1209 else {
1210 buf_pos=new_buf_pos;
1211 bit_pos=(bit_pos+delta)%8;
1212 }
1213 }
1214
1215 int TTCN_Buffer::increase_pos_padd(int padding)
1216 {
1217 if(padding) { // <---old bit pos--->
1218 size_t new_bit_pos = ((buf_pos*8 + bit_pos + padding-1)/padding) * padding;
1219 int padded = new_bit_pos - buf_pos * 8 - bit_pos;
1220 // padded = bits skipped to reach the next multiple of padding (bits)
1221 buf_pos = new_bit_pos / 8;
1222 bit_pos = new_bit_pos % 8;
1223 return padded;
1224 }else
1225 return 0;
1226 }
1227
1228 size_t TTCN_Buffer::unread_len_bit()
1229 {
1230 return (buf_len-buf_pos)*8-bit_pos;
1231 }
1232
1233 void TTCN_Buffer::start_ext_bit(boolean p_reverse)
1234 {
1235 if (ext_level++ == 0) {
1236 start_of_ext_bit = buf_len;
1237 ext_bit_reverse = p_reverse;
1238 }
1239 }
1240
1241 void TTCN_Buffer::stop_ext_bit()
1242 {
1243 if (ext_level <= 0)
1244 TTCN_EncDec_ErrorContext::error_internal("TTCN_Buffer::stop_ext_bit() "
1245 "was called without start_ext_bit().");
1246 if (--ext_level == 0) {
1247 unsigned char one = current_bitorder ? 0x01 : 0x80;
1248 unsigned char zero= ~one;
1249 unsigned char *data_ptr = buf_ptr != NULL ? buf_ptr->data_ptr : NULL;
1250 if (ext_bit_reverse) {
1251 for(size_t a=start_of_ext_bit;a<buf_len-1;a++) data_ptr[a] |= one;
1252 data_ptr[buf_len-1] &= zero;
1253 } else {
1254 for(size_t a=start_of_ext_bit;a<buf_len-1;a++) data_ptr[a] &= zero;
1255 data_ptr[buf_len-1] |= one;
1256 }
1257 }
1258 }
1259
1260 void TTCN_Buffer::put_pad(size_t len, const unsigned char *s,
1261 int pat_len, raw_order_t fieldorder)
1262 {
1263 if(len==0) return;
1264 if(pat_len==0){
1265 put_zero(len,fieldorder);
1266 return;
1267 }
1268 RAW_coding_par cp;
1269 cp.bitorder=ORDER_LSB;
1270 cp.byteorder=ORDER_LSB;
1271 cp.fieldorder=fieldorder;
1272 cp.hexorder=ORDER_LSB;
1273 int length=len;
1274 while(length>0){
1275 put_b(length>pat_len?pat_len:length,s,cp,0);
1276 length-=pat_len;
1277 }
1278 }
1279
1280 void TTCN_Buffer::set_last_bit(boolean p_last_bit)
1281 {
1282 unsigned char *last_bit_ptr = buf_ptr->data_ptr + last_bit_pos;
1283 unsigned char bitmask = 0x01 << last_bit_bitpos;
1284 if (p_last_bit) *last_bit_ptr |= bitmask;
1285 else *last_bit_ptr &= ~bitmask;
1286 }
1287
1288 unsigned char TTCN_Buffer::get_byte_rev(const unsigned char* data,
1289 size_t len, size_t idx)
1290 {
1291 unsigned char ch='\0';
1292 size_t hossz=(len+7)/8-1;
1293 int bit_limit=len%8;
1294 if(idx>hossz) return ch;
1295 if(bit_limit==0)return data[hossz-idx];
1296 ch=data[hossz-idx]<<(8-bit_limit);
1297 if((hossz-idx)>0) ch|=(data[hossz-idx-1]>>bit_limit)
1298 &BitMaskTable[8-bit_limit];
1299 return ch;
1300 }
1301
1302 unsigned char TTCN_Buffer::get_byte_align(size_t len,
1303 raw_order_t fieldorder,
1304 raw_order_t req_align,
1305 size_t idx)
1306 {
1307 if(idx>(bit_pos+len)/8) return '\0';
1308 const unsigned char *data_ptr = buf_ptr != NULL ? buf_ptr->data_ptr : NULL;
1309 if(idx==0){ // first byte
1310 if(fieldorder==req_align){
1311 if(fieldorder==ORDER_LSB){
1312 return data_ptr[buf_pos]>>bit_pos;
1313 }
1314 else {return data_ptr[buf_pos]<<bit_pos;}
1315 }
1316 else {return data_ptr[buf_pos];}
1317 }
1318 if(idx==(bit_pos+len)/8){ // last byte
1319 if(fieldorder==req_align){
1320 if(fieldorder==ORDER_LSB){
1321 return data_ptr[buf_pos+idx]<<(8-(bit_pos+len)%8);
1322 }
1323 else {return data_ptr[buf_pos+idx]>>(8-(bit_pos+len)%8);}
1324 }
1325 else {return data_ptr[buf_pos+idx];}
1326 }
1327 return data_ptr[buf_pos+idx];
1328 }
This page took 0.058565 seconds and 5 git commands to generate.