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
16 * Szabo, Janos Zoltan – initial implementation
18 * Zalanyi, Balazs Andor
20 ******************************************************************************/
23 #include "../common/memory.h"
24 #include "Octetstring.hh"
25 #include "Charstring.hh"
26 #include "String_struct.hh"
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
,
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
,
89 TTCN_EncDec::error_type_t
TTCN_EncDec::last_error_type
=ET_NONE
;
90 char *TTCN_EncDec::error_str
=NULL
;
92 static TTCN_EncDec::error_type_t
& operator++(TTCN_EncDec::error_type_t
& eb
)
95 =(eb
==TTCN_EncDec::ET_NONE
)
96 ?TTCN_EncDec::ET_UNDEF
97 :TTCN_EncDec::error_type_t(eb
+1);
100 void TTCN_EncDec::set_error_behavior(error_type_t p_et
, error_behavior_t p_eb
)
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
) {
106 for(error_type_t i
=ET_UNDEF
; i
<ET_ALL
; ++i
)
107 error_behavior
[i
]=default_error_behavior
[i
];
109 error_behavior
[p_et
]=default_error_behavior
[p_et
];
113 for(error_type_t i
=ET_UNDEF
; i
<ET_ALL
; ++i
)
114 error_behavior
[i
]=p_eb
;
116 error_behavior
[p_et
]=p_eb
;
120 TTCN_EncDec::error_behavior_t
121 TTCN_EncDec::get_error_behavior(error_type_t p_et
)
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
];
128 TTCN_EncDec::error_behavior_t
129 TTCN_EncDec::get_default_error_behavior(error_type_t p_et
)
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
];
136 void TTCN_EncDec::clear_error()
138 last_error_type
=ET_NONE
;
139 Free(error_str
); error_str
=NULL
;
142 void TTCN_EncDec::error(error_type_t p_et
, char *msg
)
144 last_error_type
=p_et
;
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
);
160 TTCN_EncDec_ErrorContext
*TTCN_EncDec_ErrorContext::head
=NULL
;
161 TTCN_EncDec_ErrorContext
*TTCN_EncDec_ErrorContext::tail
=NULL
;
163 TTCN_EncDec_ErrorContext::TTCN_EncDec_ErrorContext()
167 if(tail
) tail
->next
=this;
173 TTCN_EncDec_ErrorContext::TTCN_EncDec_ErrorContext(const char *fmt
, ...)
177 msg
=mprintf_va_list(fmt
, args
);
180 if(tail
) tail
->next
=this;
186 TTCN_EncDec_ErrorContext::~TTCN_EncDec_ErrorContext()
190 TTCN_error("Internal error:"
191 " TTCN_EncDec_ErrorContext::~TTCN_EncDec_ErrorContext()");
192 if(prev
) prev
->next
=NULL
;
197 void TTCN_EncDec_ErrorContext::set_msg(const char *fmt
, ...)
202 msg
=mprintf_va_list(fmt
, args
);
206 void TTCN_EncDec_ErrorContext::error(TTCN_EncDec::error_type_t p_et
,
207 const char *fmt
, ...)
210 for(TTCN_EncDec_ErrorContext
*p
=head
; p
!=NULL
; p
=p
->next
)
211 err_msg
=mputstr(err_msg
, p
->msg
);
213 va_start(parameters
, fmt
);
214 err_msg
=mputprintf_va_list(err_msg
, fmt
, parameters
);
216 TTCN_EncDec::error(p_et
, err_msg
);
219 void TTCN_EncDec_ErrorContext::error_internal(const char *fmt
, ...)
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
);
225 va_start(parameters
, fmt
);
226 err_msg
=mputprintf_va_list(err_msg
, fmt
, parameters
);
228 TTCN_EncDec::error(TTCN_EncDec::ET_INTERNAL
, err_msg
);
229 TTCN_error("%s", TTCN_EncDec::get_error_str());
232 void TTCN_EncDec_ErrorContext::warning(const char *fmt
, ...)
235 for(TTCN_EncDec_ErrorContext
*p
=head
; p
!=NULL
; p
=p
->next
)
236 warn_msg
=mputstr(warn_msg
, p
->msg
);
238 va_start(parameters
, fmt
);
239 warn_msg
=mputprintf_va_list(warn_msg
, fmt
, parameters
);
241 TTCN_warning("%s", warn_msg
);
245 #define INITIAL_SIZE 1024
246 #define MEMORY_SIZE(n) (sizeof(buffer_struct) - sizeof(int) + (n))
248 void TTCN_Buffer::reset_buffer()
254 start_of_ext_bit
= 0;
256 current_bitorder
= FALSE
;
257 ext_bit_reverse
= FALSE
;
261 void TTCN_Buffer::release_memory()
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
);
267 TTCN_EncDec_ErrorContext::error_internal("Invalid reference counter %u "
268 "when freeing a TTCN_Buffer.", buf_ptr
->ref_count
);
273 size_t TTCN_Buffer::get_memory_size(size_t target_size
)
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
;
280 // integer overflow occurred
281 return static_cast<size_t>(-1);
287 void TTCN_Buffer::copy_memory()
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
);
299 void TTCN_Buffer::increase_size(size_t size_incr
)
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
));
312 memset(buf_ptr
->data_ptr
,0, buf_size
);
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
));
320 memset(buf_ptr
->data_ptr
+ buf_len
,0, buf_size
- buf_len
);
323 } else { // a brand new buffer
324 buf_size
= get_memory_size(size_incr
);
325 buf_ptr
= (buffer_struct
*)Malloc(MEMORY_SIZE(buf_size
));
327 memset(buf_ptr
->data_ptr
,0, buf_size
);
329 buf_ptr
->ref_count
= 1;
333 TTCN_Buffer::TTCN_Buffer()
341 TTCN_Buffer::TTCN_Buffer(const TTCN_Buffer
& p_buf
)
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
;
350 TTCN_Buffer::TTCN_Buffer(const OCTETSTRING
& p_os
)
352 p_os
.must_bound("Initializing a TTCN_Buffer with an unbound octetstring "
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
;
361 TTCN_Buffer::TTCN_Buffer(const CHARSTRING
& p_cs
)
363 p_cs
.must_bound("Initializing a TTCN_Buffer with an unbound charstring "
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
;
372 TTCN_Buffer
& TTCN_Buffer::operator=(const TTCN_Buffer
& p_buf
)
374 if (&p_buf
!= this) {
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
;
385 TTCN_Buffer
& TTCN_Buffer::operator=(const OCTETSTRING
& p_os
)
387 p_os
.must_bound("Assignment of an unbound octetstring value to a "
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
;
398 TTCN_Buffer
& TTCN_Buffer::operator=(const CHARSTRING
& p_cs
)
400 p_cs
.must_bound("Assignment of an unbound charstring value to a "
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
;
411 void TTCN_Buffer::clear()
420 const unsigned char* TTCN_Buffer::get_data() const
422 if (buf_ptr
!= NULL
) return buf_ptr
->data_ptr
;
426 const unsigned char* TTCN_Buffer::get_read_data() const
428 if (buf_ptr
!= NULL
) return buf_ptr
->data_ptr
+ buf_pos
;
432 void TTCN_Buffer::set_pos(size_t new_pos
)
434 if (new_pos
< buf_len
) buf_pos
= new_pos
;
435 else buf_pos
= buf_len
;
438 void TTCN_Buffer::increase_pos(size_t delta
)
440 size_t new_buf_pos
=buf_pos
+delta
;
441 if(new_buf_pos
<buf_pos
|| new_buf_pos
>buf_len
)
447 void TTCN_Buffer::get_end(unsigned char*& end_ptr
, size_t& end_len
)
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
;
455 void TTCN_Buffer::increase_length(size_t size_incr
)
457 if (buf_size
< buf_len
+ size_incr
) increase_size(size_incr
);
458 buf_len
+= size_incr
;
461 void TTCN_Buffer::put_c(unsigned char c
)
464 buf_ptr
->data_ptr
[buf_len
] = c
;
468 void TTCN_Buffer::put_s(size_t len
, const unsigned char *s
)
472 memcpy(buf_ptr
->data_ptr
+ buf_len
, s
, len
);
477 void TTCN_Buffer::put_string(const OCTETSTRING
& p_os
)
479 p_os
.must_bound("Appending an unbound octetstring value to a TTCN_Buffer.");
480 if (p_os
.val_ptr
->n_octets
> 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
;
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
;
496 void TTCN_Buffer::put_string(const CHARSTRING
& p_cs
)
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
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
;
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
,
522 buf_len
+= p_buf
.buf_len
;
524 else { // share the data
530 void TTCN_Buffer::get_string(OCTETSTRING
& p_os
)
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
);
538 if (buf_size
!= buf_len
) {
539 buf_ptr
= (buffer_struct
*)Realloc(buf_ptr
, MEMORY_SIZE(buf_len
));
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
;
546 } else p_os
.init_struct(0);
549 void TTCN_Buffer::get_string(CHARSTRING
& p_cs
)
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;
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';
568 } else p_cs
.init_struct(0);
571 void TTCN_Buffer::get_string(UNIVERSAL_CHARSTRING
& p_cs
)
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);
581 void TTCN_Buffer::cut()
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
;
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
);
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
));
614 void TTCN_Buffer::cut_end()
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
) {
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
));
640 start_of_ext_bit
= 0;
642 current_bitorder
= FALSE
;
643 ext_bit_reverse
= FALSE
;
647 boolean
TTCN_Buffer::contains_complete_TLV()
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
);
656 void TTCN_Buffer::log() const
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
);
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
]);
668 TTCN_Logger::log_char(')');
671 void TTCN_Buffer::put_b(size_t len
, const unsigned char *s
,
672 const RAW_coding_par
& coding_par
, int align
)
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
;
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"
693 printf("local bito:%s,field:%s\r\n",local_bitorder==ORDER_MSB?"M":"L",
694 local_fieldorder==ORDER_MSB?"M":"L"
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));
702 memcpy(st
,s
,(len
+7)/8*sizeof(unsigned char));
703 if(len
%8) st
[(len
+7)/8-1]&=BitMaskTable
[len
%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
++){
713 ptr
[a
]|=s
[a
]<<(8-bit_bound
);
714 if(a
<max_index
) ptr
[a
+1]=s
[a
]>>bit_bound
;
718 memcpy(st
+loc_align
/8,s
,(len
+7)/8*sizeof(unsigned char));
725 if(coding_par
.byteorder
==ORDER_MSB
) align
=-align
;
726 if(align
<0) put_zero(loc_align
,local_fieldorder
);
727 else must_align
=true;
731 if(must_align
) put_zero(loc_align
,local_fieldorder
);
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
);
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));
745 for(size_t a
=1;a
<(len
+7)/8;a
++){
746 unsigned char ch
='\0';
748 st2
[a
-1]=(st2
[a
-1]&0x0f)|(s
[a
]<<4);
749 st2
[a
]=(s
[a
]&0xf0)|ch
;
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;
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
])|
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
));
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
));
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
);
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);
788 unsigned char *prt
=data_ptr
+buf_len
;
789 for(size_t a
=0;a
<len
/8;a
++) prt
[a
]=REVERSE_BITS(s
[a
]);
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
];
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
]);
804 size_t maxindex
=new_size
-1;
805 if(coding_par
.byteorder
==ORDER_LSB
){
806 if(local_bitorder
==ORDER_LSB
){
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
821 prt
[a
]|=(sa
>>bit_pos
)&~REVERSE_BITS(mask1
);
823 prt
[a
+1]=sa
<<(8-bit_pos
);
827 for(unsigned int a
=0;a
<(len
+7)/8;a
++){
829 prt
[a
]|=s
[a
]<<bit_pos
;
831 prt
[a
+1]=s
[a
]>>(8-bit_pos
);
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
);
843 else{ // bitorder==ORDER_MSB
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
){
849 prt
[0]|=REVERSE_BITS(s
[0])>>bit_pos
;
850 prt
[1]=REVERSE_BITS(s
[0])<<(8-bit_pos
);
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
);
857 for(unsigned int a
=1;a
<(len
+7)/8;a
++){
859 prt
[a
]|=REVERSE_BITS(s
[a
])>>bit_pos
;
861 prt
[a
+1]=REVERSE_BITS(s
[a
])<<(8-bit_pos
);
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
]);
868 if(local_fieldorder
==ORDER_LSB
&& new_bit_pos
)
869 data_ptr
[new_size
-1]>>=(8-new_bit_pos
);
872 else{ // byteorder==ORDER_MSB
873 if(local_bitorder
==ORDER_LSB
){
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
);
881 prt
[1]=ch
<<(8-bit_pos
);
886 prt
[1]=ch
<<(8-bit_pos
);
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
);
893 prt
[a
+1]=ch
<<(8-bit_pos
);
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
);
900 if(local_fieldorder
==ORDER_LSB
&& new_bit_pos
)
901 data_ptr
[new_size
-1]>>=(8-new_bit_pos
);
903 else{ // bitorder==ORDER_MSB
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
);
915 prt
[0]|=REVERSE_BITS(ch
)<<bit_pos
;
916 prt
[1]=REVERSE_BITS(ch
)>>(8-bit_pos
);
918 for(unsigned int a
=1;a
<(len
+7)/8;a
++){
919 ch
=get_byte_rev(s
,len
,a
);
921 prt
[a
]|=REVERSE_BITS(ch
)<<bit_pos
;
923 prt
[a
+1]=REVERSE_BITS(ch
)>>(8-bit_pos
);
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
));
931 if(local_fieldorder
==ORDER_MSB
&& new_bit_pos
)
932 data_ptr
[new_size
-1]<<=(8-new_bit_pos
);
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;
942 last_bit_bitpos=7-(bit_pos+len-1)%8;*/
946 last_bit_pos
=buf_len
-1;
947 if(local_fieldorder
==ORDER_LSB
)
948 last_bit_bitpos
=bit_pos
-1;
950 last_bit_bitpos
=7-(bit_pos
-1);
953 last_bit_pos
=buf_len
-1;
954 if(local_fieldorder
==ORDER_LSB
)
959 if(must_align
) put_zero(loc_align
,local_fieldorder
);
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
)
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
;
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
;
982 s
[0]=data_ptr
[buf_pos
]>>(8-bit_pos
-len
);
986 if(local_fieldorder
==ORDER_LSB
){
987 s
[0]=REVERSE_BITS(data_ptr
[buf_pos
])>>(8-bit_pos
-len
);
989 s
[0]=REVERSE_BITS(data_ptr
[buf_pos
])>>bit_pos
;
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));
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
]);
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
];
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
]);
1015 size_t num_bytes
= (len
+ 7) / 8;
1016 if(coding_par
.byteorder
==ORDER_LSB
){
1017 if(local_bitorder
==ORDER_LSB
){
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)
1024 ((get_byte_align(len
,local_fieldorder
,ORDER_MSB
,a
)
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
)
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
);
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
);
1047 else{ // bitorder==ORDER_MSB
1049 unsigned char mask1
=BitMaskTable
[bit_pos
];
1050 for(unsigned int a
=0;a
<num_bytes
;a
++){
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
)
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
);
1066 else{ // byteorder==ORDER_MSB
1067 if(local_bitorder
==ORDER_LSB
){
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)
1078 // unsigned char *prt=data_ptr+buf_pos;
1079 for(unsigned int a
=0,b
=new_buf_pos
-1;a
<num_bytes
;a
++,b
--)
1081 if(local_fieldorder
==ORDER_LSB
&& bit_pos
)
1082 s
[num_bytes
-1]>>=bit_pos
;
1085 else{ // bitorder==ORDER_MSB
1087 // unsigned char mask1=BitMaskTable[new_bit_pos];
1088 for(unsigned int a
=0,b
=(bit_pos
+len
)/8;a
<num_bytes
;a
++,b
--){
1090 (get_byte_align(len
,local_fieldorder
,ORDER_MSB
,b
)
1092 (get_byte_align(len
,local_fieldorder
,ORDER_MSB
,b
-1)
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
;
1106 if(coding_par
.hexorder
==ORDER_MSB
){
1108 for(size_t a
=1;a
<(len
+7)/8;a
++){
1109 unsigned char ch
='\0';
1111 s
[a
-1]=(s
[a
-1]&0x0f)|(s
[a
]<<4);
1112 s
[a
]=(s
[a
]&0xf0)|ch
;
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;
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
;
1128 buf_pos
=new_buf_pos
;
1129 bit_pos
=new_bit_pos
;
1132 void TTCN_Buffer::put_zero(size_t len
, raw_order_t fieldorder
)
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
);
1138 unsigned char *data_ptr
= buf_ptr
!= NULL
? buf_ptr
->data_ptr
: NULL
;
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);
1148 if(fieldorder
==ORDER_LSB
)
1149 data_ptr
[new_size
-1]=data_ptr
[new_size
-1]&BitMaskTable
[bit_pos
];
1151 data_ptr
[new_size
-1]=data_ptr
[new_size
-1]&
1152 REVERSE_BITS(BitMaskTable
[bit_pos
]);
1156 memset(data_ptr
+buf_len
, 0, (len
+7)/8);
1159 bit_pos
=(bit_pos
+len
)%8;
1161 last_bit_pos
=buf_len
-1;
1162 if(fieldorder
==ORDER_LSB
)
1163 last_bit_bitpos
=bit_pos
-1;
1165 last_bit_bitpos
=7-(bit_pos
-1);
1168 last_bit_pos
=buf_len
-1;
1169 if(fieldorder
==ORDER_LSB
)
1176 const unsigned char* TTCN_Buffer::get_read_data(size_t &bitpos
) const
1179 if (buf_ptr
!= NULL
) return buf_ptr
->data_ptr
+ buf_pos
;
1183 void TTCN_Buffer::set_pos(size_t pos
, size_t bitpos
)
1185 buf_pos
=pos
<buf_len
?pos
:buf_len
;
1190 void TTCN_Buffer::set_pos_bit(size_t new_bit_pos
)
1192 size_t new_pos
= new_bit_pos
/ 8;
1193 if (new_pos
< buf_len
) {
1195 bit_pos
= new_bit_pos
% 8;
1202 void TTCN_Buffer::increase_pos_bit(size_t delta
)
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
) {
1210 buf_pos
=new_buf_pos
;
1211 bit_pos
=(bit_pos
+delta
)%8;
1215 int TTCN_Buffer::increase_pos_padd(int padding
)
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;
1228 size_t TTCN_Buffer::unread_len_bit()
1230 return (buf_len
-buf_pos
)*8-bit_pos
;
1233 void TTCN_Buffer::start_ext_bit(boolean p_reverse
)
1235 if (ext_level
++ == 0) {
1236 start_of_ext_bit
= buf_len
;
1237 ext_bit_reverse
= p_reverse
;
1241 void TTCN_Buffer::stop_ext_bit()
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
;
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
;
1260 void TTCN_Buffer::put_pad(size_t len
, const unsigned char *s
,
1261 int pat_len
, raw_order_t fieldorder
)
1265 put_zero(len
,fieldorder
);
1269 cp
.bitorder
=ORDER_LSB
;
1270 cp
.byteorder
=ORDER_LSB
;
1271 cp
.fieldorder
=fieldorder
;
1272 cp
.hexorder
=ORDER_LSB
;
1275 put_b(length
>pat_len
?pat_len
:length
,s
,cp
,0);
1280 void TTCN_Buffer::set_last_bit(boolean p_last_bit
)
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
;
1288 unsigned char TTCN_Buffer::get_byte_rev(const unsigned char* data
,
1289 size_t len
, size_t idx
)
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
];
1302 unsigned char TTCN_Buffer::get_byte_align(size_t len
,
1303 raw_order_t fieldorder
,
1304 raw_order_t req_align
,
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
;
1314 else {return data_ptr
[buf_pos
]<<bit_pos
;}
1316 else {return data_ptr
[buf_pos
];}
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);
1323 else {return data_ptr
[buf_pos
+idx
]>>(8-(bit_pos
+len
)%8);}
1325 else {return data_ptr
[buf_pos
+idx
];}
1327 return data_ptr
[buf_pos
+idx
];