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