Gamp v0.0.8
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
octets.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020-2026 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef JAU_OCTETS_HPP_
26#define JAU_OCTETS_HPP_
27
28#include <algorithm>
29#include <cstdint>
30#include <cstring>
31#include <initializer_list>
32#include <memory>
33#include <string>
34#include <string_view>
35#include "jau/cpp_lang_util.hpp"
36#include "jau/int_types.hpp"
37
38#include <jau/basic_types.hpp>
39#include <jau/debug.hpp>
40#include <jau/io/eui48.hpp>
41#include <jau/secmem.hpp>
42#include <jau/uuid.hpp>
43
44// #define JAU_TRACE_OCTETS 1
45#ifdef JAU_TRACE_OCTETS
46 #define JAU_TRACE_OCTETS_PRINT(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); }
47#else
48 #define JAU_TRACE_OCTETS_PRINT(...)
49#endif
50
51namespace jau {
52
53 /** \addtogroup ByteUtils
54 *
55 * @{
56 */
57
58 /**
59 * Transient read only and endian aware octet data, i.e. non persistent passthrough, owned by caller.
60 *
61 * Endian byte order is passed at construction.
62 *
63 * Constructor and assignment operations are `noexcept`. In case invalid arguments are passed, abort() is being called.
64 * This is a design choice based on reusing already existing underlying resources.
65 */
67 {
68 private:
69 /** Used memory size <= capacity, maybe zero. */
70 nsize_t _size;
71 /** Memory pointer, might be nullptr. Actual capacity known by owner, e.g. POctets. */
72 uint8_t * _data;
73 /** byte-order flag, little or big endian */
74 lb_endian_t _byte_order;
75
76 protected:
77 /**
78 * Validates the given data_ and size_.
79 *
80 * Aborts if data_ is nullptr and size_ > 0.
81 *
82 * @param data_ a memory pointer
83 * @param size_ claimed memory size
84 */
85 static inline void checkPtr(uint8_t *data_, nsize_t size_) noexcept {
86 if( nullptr == data_ && 0 < size_ ) {
87 jau_ABORT("TROOctets: nullptr with size %s > 0", std::to_string(size_).c_str());
88 abort(); // never reached
89 }
90 }
91
92 constexpr uint8_t * data() noexcept { return _data; }
93
94 /**
95 * Internally sets the _size and _data fields after validation.
96 *
97 * Aborts if data_ is nullptr and size_ > 0.
98 *
99 * @param data_ a memory pointer
100 * @param size_ used memory size
101 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
102 */
103 inline void setData(uint8_t *data_, nsize_t size_, const lb_endian_t byte_order) noexcept {
104 JAU_TRACE_OCTETS_PRINT("POctets setData: %zu bytes @ %p -> %zu bytes @ %p",
105 _size, _data, size_, data_);
106 checkPtr(data_, size_);
107 _size = size_;
108 _data = data_;
109 _byte_order = byte_order;
110 }
111 constexpr void setSize(nsize_t s) noexcept { _size = s; }
112
113 public:
114 /**
115 * Transient passthrough read-only memory, w/o ownership ..
116 *
117 * Aborts if source is nullptr and len > 0.
118 *
119 * @param source a non nullptr memory, otherwise throws exception. Actual capacity known by owner.
120 * @param len readable size of the memory, may be zero
121 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
122 */
123 TROOctets(const uint8_t *source, const nsize_t len, const lb_endian_t byte_order_val ) noexcept
124 : _size( len ), _data( const_cast<uint8_t *>(source) ),
125 _byte_order( byte_order_val )
126 {
127 checkPtr(_data, _size);
128 }
129
130 /**
131 * Default constructor with nullptr memory, zero size and lb_endian::native byte order.
132 *
133 * Conveniently exists to allow instantiation of variables
134 * intended for later assignment.
135 */
136 TROOctets() noexcept
137 : _size( 0 ), _data( nullptr ),
138 _byte_order( lb_endian_t::native )
139 { }
140
141 TROOctets(const TROOctets &o) noexcept = default;
142 TROOctets(TROOctets &&o) noexcept = default;
143 TROOctets& operator=(const TROOctets &o) noexcept = default;
144 TROOctets& operator=(TROOctets &&o) noexcept = default;
145
146 virtual ~TROOctets() noexcept = default;
147
148 inline void check_range(const nsize_t i, const nsize_t count, const char *file, int line) const {
149 if( i+count > _size ) {
150 throw IndexOutOfBoundsError(i, count, _size, file, line);
151 }
152 }
153
154 constexpr bool is_range_valid(const nsize_t i, const nsize_t count) const noexcept {
155 return i+count <= _size;
156 }
157
158 /** Returns byte order of this octet store. */
159 constexpr lb_endian_t byte_order() const noexcept { return _byte_order; }
160
161 /** Returns the used memory size for read and write operations, may be zero. */
162 constexpr nsize_t size() const noexcept { return _size; }
163
164 uint8_t get_uint8(const nsize_t i) const {
166 return _data[i];
167 }
168 constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept {
169 return _data[i];
170 }
171
172 int8_t get_int8(const nsize_t i) const {
174 return jau::get_int8(_data + i);
175 }
176 constexpr int8_t get_int8_nc(const nsize_t i) const noexcept {
177 return jau::get_int8(_data + i);
178 }
179
180 uint16_t get_uint16(const nsize_t i) const {
182 return jau::get_uint16(_data + i, byte_order());
183 }
184 constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept {
185 return jau::get_uint16(_data + i, byte_order());
186 }
187
188 uint32_t get_uint32(const nsize_t i) const {
190 return jau::get_uint32(_data + i, byte_order());
191 }
192 constexpr uint32_t get_uint32_nc(const nsize_t i) const noexcept {
193 return jau::get_uint32(_data + i, byte_order());
194 }
195
198 return jau::io::net::EUI48(_data+i, byte_order() );
199 }
200 inline jau::io::net::EUI48 get_eui48_nc(const nsize_t i) const noexcept {
201 return jau::io::net::EUI48(_data+i, byte_order() );
202 }
203
204 uint64_t get_uint64(const nsize_t i) const {
206 return jau::get_uint64(_data + i, byte_order());
207 }
208 constexpr uint64_t get_uint64_nc(const nsize_t i) const noexcept {
209 return jau::get_uint64(_data + i, byte_order());
210 }
211
214 return jau::get_uint128(_data + i, byte_order());
215 }
216 constexpr uint128dp_t get_uint128_nc(const nsize_t i) const noexcept {
217 return jau::get_uint128(_data + i, byte_order());
218 }
219
222 return jau::get_uint192(_data + i, byte_order());
223 }
224 constexpr uint192dp_t get_uint192_nc(const nsize_t i) const noexcept {
225 return jau::get_uint192(_data + i, byte_order());
226 }
227
230 return jau::get_uint256(_data + i, byte_order());
231 }
232 constexpr uint256dp_t get_uint256_nc(const nsize_t i) const noexcept {
233 return jau::get_uint256(_data + i, byte_order());
234 }
235
236 /** Assumes a null terminated string */
237 std::string get_string(const nsize_t i) const {
238 check_range(i, 1, E_FILE_LINE); // minimum size
239 return std::string( (const char*)(_data+i) );
240 }
241 /** Assumes a null terminated string */
242 inline std::string get_string_nc(const nsize_t i) const noexcept {
243 return std::string( (const char*)(_data+i) );
244 }
245
246 /** Assumes a string with defined length, not necessarily null terminated */
247 std::string get_string(const nsize_t i, const nsize_t length) const {
248 check_range(i, length, E_FILE_LINE);
249 return std::string( (const char*)(_data+i), length );
250 }
251
252 uuid16_t get_uuid16(const nsize_t i) const {
253 return uuid16_t(get_uint16(i));
254 }
255 inline uuid16_t get_uuid16_nc(const nsize_t i) const noexcept {
256 return uuid16_t(get_uint16_nc(i));
257 }
258
263 inline uuid128_t get_uuid128_nc(const nsize_t i) const noexcept {
264 return jau::get_uuid128(_data + i, byte_order());
265 }
266
267 std::unique_ptr<const uuid_t> get_uuid(const nsize_t i, const uuid_t::TypeSize tsize) const {
269 return uuid_t::create(tsize, _data + i, byte_order());
270 }
271
272 constexpr uint8_t const * get_ptr() const noexcept { return _data; }
273 uint8_t const * get_ptr(const nsize_t i) const {
275 return _data + i;
276 }
277 constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept {
278 return _data + i;
279 }
280
281 bool operator==(const TROOctets& rhs) const noexcept {
282 return _size == rhs._size && 0 == std::memcmp(_data, rhs._data, _size);
283 }
284 bool operator!=(const TROOctets& rhs) const noexcept {
285 return !(*this == rhs);
286 }
287
288 std::string toString() const noexcept {
289 std::string s;
290 do_noexcept([&]() {
291 s.append("size ")
292 .append(std::to_string(_size))
293 .append(", [").append(to_string( byte_order() )).append(", ").append(to_string( byte_order() )).append("], ro: ");
294 });
295 jau::appendHexString(s, _data, _size);
296 return s;
297 }
298 };
299
300 /**
301 * Transient endian aware octet data, i.e. non persistent passthrough, owned by caller.
302 *
303 * Endian byte order is passed at construction.
304 *
305 * Constructor and assignment operations are `noexcept`. In case invalid arguments are passed, abort() is being called.
306 * This is a design choice based on reusing already existing underlying resources.
307 */
308 class TOctets : public TROOctets
309 {
310 public:
311 /**
312 * Transient passthrough r/w memory, w/o ownership ..
313 *
314 * Aborts if source is nullptr and len > 0.
315 *
316 * @param source transient data source
317 * @param len length of transient data source
318 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
319 */
320 TOctets(uint8_t *source, const nsize_t len, const lb_endian_t byte_order) noexcept
321 : TROOctets(source, len, byte_order) {}
322
323 TOctets(const TOctets &o) noexcept = default;
324 TOctets(TOctets &&o) noexcept = default;
325 TOctets& operator=(const TOctets &o) noexcept = default;
326 TOctets& operator=(TOctets &&o) noexcept = default;
327
328 ~TOctets() noexcept override = default;
329
330 void put_int8(const nsize_t i, const int8_t v) {
332 data()[i] = static_cast<uint8_t>(v);
333 }
334 constexpr void put_int8_nc(const nsize_t i, const int8_t v) noexcept {
335 data()[i] = static_cast<uint8_t>(v);
336 }
337
338 void put_uint8(const nsize_t i, const uint8_t v) {
340 data()[i] = v;
341 }
342 constexpr void put_uint8_nc(const nsize_t i, const uint8_t v) noexcept {
343 data()[i] = v;
344 }
345
346 void put_uint16(const nsize_t i, const uint16_t v) {
348 jau::put_uint16(data() + i, v, byte_order());
349 }
350 constexpr void put_uint16_nc(const nsize_t i, const uint16_t v) noexcept {
351 jau::put_uint16(data() + i, v, byte_order());
352 }
353
354 void put_uint32(const nsize_t i, const uint32_t v) {
356 jau::put_uint32(data() + i, v, byte_order());
357 }
358 constexpr void put_uint32_nc(const nsize_t i, const uint32_t v) noexcept {
359 jau::put_uint32(data() + i, v, byte_order());
360 }
361
362 void put_eui48(const nsize_t i, const jau::io::net::EUI48 & v) {
363 check_range(i, sizeof(v.b), E_FILE_LINE);
364 v.put(data() + i, byte_order() );
365 }
366 inline void put_eui48_nc(const nsize_t i, const jau::io::net::EUI48 & v) noexcept {
367 v.put(data() + i, byte_order() );
368 }
369
370 void put_uint64(const nsize_t i, const uint64_t & v) {
372 jau::put_uint64(data() + i, v, byte_order());
373 }
374 constexpr void put_uint64_nc(const nsize_t i, const uint64_t & v) noexcept {
375 jau::put_uint64(data() + i, v, byte_order());
376 }
377
378 void put_uint128(const nsize_t i, const uint128dp_t & v) {
380 jau::put_uint128(data() + i, v, byte_order());
381 }
382 constexpr void put_uint128_nc(const nsize_t i, const uint128dp_t & v) noexcept {
383 jau::put_uint128(data() + i, v, byte_order());
384 }
385
386 void put_uint192(const nsize_t i, const uint192dp_t & v) {
388 jau::put_uint192(data() + i, v, byte_order());
389 }
390 constexpr void put_uint192_nc(const nsize_t i, const uint192dp_t & v) noexcept {
391 jau::put_uint192(data() + i, v, byte_order());
392 }
393
394 void put_uint256(const nsize_t i, const uint256dp_t & v) {
396 jau::put_uint256(data() + i, v, byte_order());
397 }
398 constexpr void put_uint256_nc(const nsize_t i, const uint256dp_t & v) noexcept {
399 jau::put_uint256(data() + i, v, byte_order());
400 }
401
402 void put_octets(const nsize_t i, const TROOctets & v) {
404 std::memcpy(data() + i, v.get_ptr(), v.size());
405 }
406 void put_octets_nc(const nsize_t i, const TROOctets & v) noexcept {
407 std::memcpy(data() + i, v.get_ptr(), v.size());
408 }
409 void put_octets(const nsize_t i, const TROOctets & v, const nsize_t v_off, const nsize_t v_len) {
410 const nsize_t size = std::min(v.size()-v_off, v_len);
412 std::memcpy(data() + i, v.get_ptr() + v_off, size);
413 }
414 void put_octets_nc(const nsize_t i, const TROOctets & v, const nsize_t v_off, const nsize_t v_len) noexcept {
415 const nsize_t size = std::min(v.size()-v_off, v_len);
416 std::memcpy(data() + i, v.get_ptr() + v_off, size);
417 }
418
419 void put_bytes(const nsize_t i, const uint8_t *source, const nsize_t byte_count) {
420 check_range(i, byte_count, E_FILE_LINE);
421 std::memcpy(data() + i, source, byte_count);
422 }
423 void put_bytes_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept {
424 std::memcpy(data() + i, source, byte_count);
425 }
426
427 void memmove(const nsize_t i, const uint8_t *source, const nsize_t byte_count) {
428 check_range(i, byte_count, E_FILE_LINE);
429 std::memmove(data() + i, source, byte_count);
430 }
431 void memmove_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept {
432 std::memmove(data() + i, source, byte_count);
433 }
434
435 void memset(const nsize_t i, const uint8_t c, const nsize_t byte_count) {
436 check_range(i, byte_count, E_FILE_LINE);
437 std::memset(data() + i, c, byte_count);
438 }
439 void memset_nc(const nsize_t i, const uint8_t c, const nsize_t byte_count) noexcept {
440 std::memset(data() + i, c, byte_count);
441 }
442 void bzero(const nsize_t i, const nsize_t byte_count) {
443 check_range(i, byte_count, E_FILE_LINE);
444 zero_bytes_sec(data() + i, byte_count);
445 }
446 void bzero_nc(const nsize_t i, const nsize_t byte_count) noexcept {
447 zero_bytes_sec(data() + i, byte_count);
448 }
449 void bzero() noexcept {
450 if( size() > 0 ) {
452 }
453 }
454
455 void put_string(const nsize_t i, const std::string & v, const nsize_t max_len, const bool includeEOS) {
456 const nsize_t size1 = v.size() + ( includeEOS ? 1 : 0 );
457 const nsize_t size = std::min(size1, max_len);
459 std::memcpy(data() + i, v.c_str(), size);
460 if( size < size1 && includeEOS ) {
461 *(data() + i + size - 1) = 0; // ensure EOS
462 }
463 }
464 void put_string_nc(const nsize_t i, const std::string & v, const nsize_t max_len, const bool includeEOS) noexcept {
465 const nsize_t size1 = v.size() + ( includeEOS ? 1 : 0 );
466 const nsize_t size = std::min(size1, max_len);
467 std::memcpy(data() + i, v.c_str(), size);
468 if( size < size1 && includeEOS ) {
469 *(data() + i + size - 1) = 0; // ensure EOS
470 }
471 }
472
473 void put_uuid(const nsize_t i, const uuid_t & v) {
475 v.put(data() + i, byte_order());
476 }
477 void put_uuid_nc(const nsize_t i, const uuid_t & v) noexcept {
478 v.put(data() + i, byte_order());
479 }
480
481 inline uint8_t * get_wptr() noexcept { return data(); }
482
483 uint8_t * get_wptr(const nsize_t i) {
485 return data() + i;
486 }
487 inline uint8_t * get_wptr_nc(const nsize_t i) noexcept {
488 return data() + i;
489 }
490
491 std::string toString() const noexcept {
492 return string_noexcept([&](){ return "size "+std::to_string(size())+", rw: "+toHexString(get_ptr(), size()); });
493 }
494 };
495
496 /**
497 * Transient endian aware octet data slice, i.e. a view of an TOctet.
498 *
499 * Endian byte order is defined by its parent TOctet.
500 */
502 {
503 private:
504 const TOctets & _parent;
505 nsize_t const _offset;
506 nsize_t const _size;
507
508 public:
509 /**
510 * Creates a view of a given TOctet with the specified offset_ and size_.
511 *
512 * @param buffer_ the parent TOctet buffer
513 * @param offset_ offset to the parent TOctet buffer
514 * @param size_ size of this view, starting at offset_
515 * @throws IndexOutOfBoundsException if offset_ + size_ > parent buffer_.size()
516 */
517 TOctetSlice(const TOctets &buffer_, const nsize_t offset_, const nsize_t size_)
518 : _parent(buffer_), _offset(offset_), _size(size_)
519 {
520 if( offset_+_size > buffer_.size() ) {
521 throw IndexOutOfBoundsError(offset_, _size, buffer_.size(), E_FILE_LINE);
522 }
523 }
524
525 /** Returns byte order of this octet store. */
526 constexpr lb_endian_t byte_order() const noexcept { return _parent.byte_order(); }
527
528 constexpr nsize_t size() const noexcept { return _size; }
529 constexpr nsize_t offset() const noexcept { return _offset; }
530 constexpr const TOctets& parent() const noexcept { return _parent; }
531
532 uint8_t get_uint8(const nsize_t i) const {
533 return _parent.get_uint8(_offset+i);
534 }
535 constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept {
536 return _parent.get_uint8_nc(_offset+i);
537 }
538
539 uint16_t get_uint16(const nsize_t i) const {
540 return _parent.get_uint16(_offset+i);
541 }
542 constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept {
543 return _parent.get_uint16_nc(_offset+i);
544 }
545
546 uint8_t const * get_ptr(const nsize_t i) const {
547 return _parent.get_ptr(_offset+i);
548 }
549 constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept {
550 return _parent.get_ptr_nc(_offset+i);
551 }
552
553 std::string toString() const noexcept {
554 return string_noexcept([&](){ return "offset "+std::to_string(_offset)+", size "+std::to_string(_size)+": "+toHexString(_parent.get_ptr()+_offset, _size); } );
555 }
556 };
557
558 /**
559 * Persistent endian aware octet data, i.e. owned dynamic heap memory allocation.
560 *
561 * Endian byte order is passed at construction.
562 *
563 * Constructor and assignment operations are **not** completely `noexcept` and may throw exceptions.
564 * This is a design choice based on dynamic resource allocation performed by this class.
565 */
566 class POctets : public TOctets
567 {
568 private:
569 nsize_t _capacity;
570
571 void freeData() {
572 uint8_t * ptr = data();
573 if( nullptr != ptr ) {
574 JAU_TRACE_OCTETS_PRINT("POctets release: %p", ptr);
575 free(ptr);
576 } // else: zero sized POctets w/ nullptr are supported
577 }
578
579 /**
580 * Allocate a memory chunk.
581 * @param size
582 * @return
583 * @throws OutOfMemoryError if running out of memory
584 */
585 [[nodiscard]] static uint8_t * allocData(const nsize_t size) {
586 if( size <= 0 ) {
587 return nullptr;
588 }
589 uint8_t * m = static_cast<uint8_t*>( std::malloc(size) );
590 if( nullptr == m ) {
591 throw OutOfMemoryError("allocData size "+std::to_string(size)+" -> nullptr", E_FILE_LINE);
592 }
593 return m;
594 }
595
596 public:
597 /** Returns the memory capacity, never zero, greater or equal size(). */
598 constexpr nsize_t capacity() const noexcept { return _capacity; }
599
600 /** Returns the remaining octets for put left, i.e. capacity() - size(). */
601 constexpr nsize_t remaining() const noexcept { return _capacity - size(); }
602
603 /**
604 * Zero sized POctets instance.
605 *
606 * Will not throw an OutOfMemoryError exception due to no allocation.
607 *
608 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
609 */
611 : TOctets(nullptr, 0, byte_order), _capacity(0)
612 {
613 JAU_TRACE_OCTETS_PRINT("POctets ctor0: zero-sized");
614 }
615
616 /**
617 * Takes ownership (malloc(size) and copy, free) ..
618 *
619 * Using explicit capacity >= source size.
620 *
621 * @param capacity_ new capacity
622 * @param source_ source data to be copied into this new instance
623 * @param size_ length of source data
624 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
625 * @throws IllegalArgumentException if capacity_ < size_
626 * @throws IllegalArgumentException if source_ is nullptr and size_ > 0
627 * @throws OutOfMemoryError if allocation fails
628 */
629 POctets(const nsize_t capacity_, const uint8_t *source_, const nsize_t size_, const lb_endian_t byte_order)
630 : TOctets( allocData(capacity_), size_, byte_order),
631 _capacity( capacity_ )
632 {
633 if( capacity() < size() ) {
634 throw IllegalArgumentError("capacity "+std::to_string(capacity())+" < size "+std::to_string(size()), E_FILE_LINE);
635 }
636 if( 0 < size_ ) {
637 if( nullptr == source_ ) {
638 throw IllegalArgumentError("source nullptr with size "+std::to_string(size_)+" > 0", E_FILE_LINE);
639 }
640 std::memcpy(data(), source_, size_);
641 }
642 JAU_TRACE_OCTETS_PRINT("POctets ctor1a: %p", data());
643 }
644
645 /**
646 * Takes ownership (malloc(size) and copy, free) ..
647 *
648 * Capacity and size will be of given source size.
649 *
650 * @param source_ source data to be copied into this new instance
651 * @param size_ length of source data
652 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
653 * @throws IllegalArgumentException if source_ is nullptr and size_ > 0
654 * @throws OutOfMemoryError if allocation fails
655 */
656 POctets(const uint8_t *source_, const nsize_t size_, const lb_endian_t byte_order)
657 : TOctets( allocData(size_), size_, byte_order),
658 _capacity( size_ )
659 {
660 if( 0 < size_ ) {
661 if( nullptr == source_ ) {
662 throw IllegalArgumentError("source nullptr with size "+std::to_string(size_)+" > 0", E_FILE_LINE);
663 }
664 std::memcpy(data(), source_, size_);
665 }
666 JAU_TRACE_OCTETS_PRINT("POctets ctor1b: %p", data());
667 }
668
669 /**
670 * Takes ownership (malloc(size) and copy, free) ..
671 *
672 * Using explicit capacity >= source size.
673 *
674 * @param capacity_ new capacity
675 * @param source_ string view source data to be copied into this new instance
676 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
677 * @throws IllegalArgumentException if capacity_ < source_.size()
678 * @throws OutOfMemoryError if allocation fails
679 */
680 POctets(const nsize_t capacity_, std::string_view source_, const lb_endian_t byte_order)
681 : TOctets( allocData(capacity_), source_.size(), byte_order),
682 _capacity( capacity_ )
683 {
684 if( capacity() < size() ) {
685 throw IllegalArgumentError("capacity "+std::to_string(capacity())+" < size "+std::to_string(size()), E_FILE_LINE);
686 }
687 if( 0 < source_.size() ) {
688 std::memcpy(data(), source_.data(), source_.size());
689 }
690 JAU_TRACE_OCTETS_PRINT("POctets ctor2a: %p", data());
691 }
692
693 /**
694 * Takes ownership (malloc(size) and copy, free) ..
695 *
696 * Capacity and size will be of given source size.
697 *
698 * @param source_ string view source data to be copied into this new instance
699 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
700 * @throws OutOfMemoryError if allocation fails
701 */
702 POctets(std::string_view source_, const lb_endian_t byte_order)
703 : TOctets( allocData(source_.size()), source_.size(), byte_order),
704 _capacity( source_.size() )
705 {
706 if( 0 < source_.size() ) {
707 std::memcpy(data(), source_.data(), source_.size());
708 }
709 JAU_TRACE_OCTETS_PRINT("POctets ctor2b: %p", data());
710 }
711
712 /**
713 * Takes ownership (malloc(size) and copy, free) ..
714 *
715 * Using explicit capacity >= source size.
716 *
717 * @param capacity_ new capacity
718 * @param sourcelist source initializer list data to be copied into this new instance with implied size
719 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
720 * @throws IllegalArgumentException if capacity_ < source_.size()
721 * @throws IllegalArgumentException if source_ is nullptr and size_ > 0
722 * @throws OutOfMemoryError if allocation fails
723 */
724 POctets(const nsize_t capacity_, std::initializer_list<uint8_t> sourcelist, const lb_endian_t byte_order)
725 : TOctets( allocData(capacity_), sourcelist.size(), byte_order),
726 _capacity( capacity_ )
727 {
728 if( capacity() < size() ) {
729 throw IllegalArgumentError("capacity "+std::to_string(capacity())+" < size "+std::to_string(size()), E_FILE_LINE);
730 }
731 if( 0 < size() ) {
732 std::memcpy(data(), sourcelist.begin(), size());
733 }
734 JAU_TRACE_OCTETS_PRINT("POctets ctor3a: %p", data());
735 }
736
737 /**
738 * Takes ownership (malloc(size) and copy, free) ..
739 *
740 * Capacity and size will be of given source size.
741 *
742 * @param sourcelist source initializer list data to be copied into this new instance with implied size
743 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
744 * @throws IllegalArgumentException if source_ is nullptr and size_ > 0
745 * @throws OutOfMemoryError if allocation fails
746 */
747 POctets(std::initializer_list<uint8_t> sourcelist, const lb_endian_t byte_order)
748 : TOctets( allocData(sourcelist.size()), sourcelist.size(), byte_order),
749 _capacity( sourcelist.size() )
750 {
751 if( 0 < size() ) {
752 std::memcpy(data(), sourcelist.begin(), size());
753 }
754 JAU_TRACE_OCTETS_PRINT("POctets ctor3b: %p", data());
755 }
756
757 /**
758 * New buffer (malloc(capacity), free)
759 *
760 * @param capacity_ new capacity
761 * @param size_ new size with size <= capacity
762 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
763 * @throws IllegalArgumentException if capacity_ < size_
764 * @throws OutOfMemoryError if allocation fails
765 */
766 POctets(const nsize_t capacity_, const nsize_t size_, const lb_endian_t byte_order)
767 : TOctets( allocData( capacity_ ), size_, byte_order ),
768 _capacity( capacity_ )
769 {
770 if( capacity() < size() ) {
771 throw IllegalArgumentError("capacity "+std::to_string(capacity())+" < size "+std::to_string(size()), E_FILE_LINE);
772 }
773 JAU_TRACE_OCTETS_PRINT("POctets ctor4a: %p", data());
774 }
775
776 /**
777 * New buffer (malloc, free)
778 *
779 * @param size new size and capacity
780 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
781 * @throws OutOfMemoryError if allocation fails
782 */
784 : TOctets( allocData( size ), size, byte_order ),
785 _capacity( size )
786 {
787 JAU_TRACE_OCTETS_PRINT("POctets ctor4b: %p", data());
788 }
789
790 /**
791 * Copy constructor
792 *
793 * Capacity of this new instance will be of source.size() only.
794 *
795 * @param source POctet source to be copied
796 * @throws OutOfMemoryError if allocation fails
797 */
798 POctets(const POctets &source)
799 : TOctets( allocData(source.size()), source.size(), source.byte_order() ),
800 _capacity( source.size() )
801 {
802 std::memcpy(data(), source.get_ptr(), source.size());
803 JAU_TRACE_OCTETS_PRINT("POctets ctor-cpy0: %p -> %p", source.get_ptr(), data());
804 }
805
806 /**
807 * Copy constructor (explicit), allowing to set a higher capacity
808 * than source.size() in contrast to the copy-constructor.
809 *
810 * @param source POctet source to be copied
811 * @param capacity_ used to determine new capacity `std::max(capacity_, source.size())`
812 * @throws OutOfMemoryError if allocation fails
813 */
814 explicit POctets(const POctets &source, const nsize_t capacity_)
815 : TOctets( allocData(source.size()), source.size(), source.byte_order() ),
816 _capacity( std::max(capacity_, source.size()) )
817 {
818 std::memcpy(data(), source.get_ptr(), source.size());
819 JAU_TRACE_OCTETS_PRINT("POctets ctor-cpy-extra1: %p -> %p", source.get_ptr(), data());
820 }
821
822 /**
823 * Move constructor
824 * @param o POctet source to be taken over
825 */
826 POctets(POctets &&o) noexcept
827 : TOctets( o.data(), o.size(), o.byte_order() ),
828 _capacity( o.capacity() )
829 {
830 // moved origin data references
831 // purge origin
832 o.setData(nullptr, 0, o.byte_order());
833 o._capacity = 0;
834 JAU_TRACE_OCTETS_PRINT("POctets ctor-move0: %p", data());
835 }
836
837 /**
838 * Assignment operator
839 * @param _source POctet source to be copied
840 * @return
841 * @throws OutOfMemoryError if allocation fails
842 */
843 POctets& operator=(const POctets &_source) {
844 if( this == &_source ) {
845 return *this;
846 }
847 freeData();
848 setData(allocData(_source.size()), _source.size(), _source.byte_order());
849 _capacity = _source.size();
850 std::memcpy(data(), _source.get_ptr(), _source.size());
851 JAU_TRACE_OCTETS_PRINT("POctets assign0: %p", data());
852 return *this;
853 }
854
855 /**
856 * Move assignment operator
857 * @param o POctet source to be taken over
858 * @return
859 */
860 POctets& operator=(POctets &&o) noexcept {
861 // move origin data references
862 setData(o.data(), o.size(), o.byte_order());
863 _capacity = o._capacity;
864 // purge origin
865 o.setData(nullptr, 0, o.byte_order());
866 o._capacity = 0;
867 JAU_TRACE_OCTETS_PRINT("POctets assign-move0: %p", data());
868 return *this;
869 }
870
871 ~POctets() noexcept override {
872 freeData();
873 setData(nullptr, 0, byte_order());
874 _capacity=0;
875 }
876
877 /**
878 * Makes a persistent POctets by copying the data from TROOctets.
879 * @param _source TROOctets to be copied
880 * @throws OutOfMemoryError if allocation fails
881 */
882 POctets(const TROOctets & _source)
883 : TOctets( allocData(_source.size()), _source.size(), _source.byte_order() ),
884 _capacity( _source.size() )
885 {
886 std::memcpy(data(), _source.get_ptr(), _source.size());
887 JAU_TRACE_OCTETS_PRINT("POctets ctor-cpy1: %p", data());
888 }
889
890 /**
891 * Assignment operator for TROOctets
892 * @param _source TROOctets to be copied
893 * @return
894 * @throws OutOfMemoryError if allocation fails
895 */
896 POctets& operator=(const TROOctets &_source) {
897 if( static_cast<TROOctets *>(this) == &_source ) {
898 return *this;
899 }
900 freeData();
901 setData(allocData(_source.size()), _source.size(), _source.byte_order());
902 _capacity = _source.size();
903 std::memcpy(data(), _source.get_ptr(), _source.size());
904 JAU_TRACE_OCTETS_PRINT("POctets assign1: %p", data());
905 return *this;
906 }
907
908 /**
909 * Makes a persistent POctets by copying the data from TOctetSlice.
910 * @param _source TROOctetSlice to be copied
911 * @throws OutOfMemoryError if allocation fails
912 */
913 POctets(const TOctetSlice & _source)
914 : TOctets( allocData(_source.size()), _source.size(), _source.byte_order() ),
915 _capacity( _source.size() )
916 {
917 std::memcpy(data(), _source.parent().get_ptr() + _source.offset(), _source.size());
918 JAU_TRACE_OCTETS_PRINT("POctets ctor-cpy2: %p", data());
919 }
920
921 /**
922 * Assignment operator for TOctetSlice
923 * @param _source TOctetSlice to be copied
924 * @return
925 * @throws OutOfMemoryError if allocation fails
926 */
927 POctets& operator=(const TOctetSlice &_source) {
928 freeData();
929 setData(allocData(_source.size()), _source.size(), _source.byte_order());
930 _capacity = _source.size();
931 std::memcpy(data(), _source.get_ptr(0), _source.size());
932 JAU_TRACE_OCTETS_PRINT("POctets assign2: %p", data());
933 return *this;
934 }
935
936 /**
937 * Resizes this instance, including its capacity
938 * @param newCapacity new capacity, must be >= newSize
939 * @param newSize new size, must be < newCapacity
940 * @return
941 * @throws OutOfMemoryError if allocation fails
942 * @throws IllegalArgumentException if newCapacity < newSize
943 */
944 POctets & resize(const nsize_t newCapacity, const nsize_t newSize) {
945 if( newCapacity < newSize ) {
946 throw IllegalArgumentError("newCapacity "+std::to_string(newCapacity)+" < newSize "+std::to_string(newSize), E_FILE_LINE);
947 }
948 if( newCapacity != _capacity ) {
949 if( newSize > size() ) {
950 recapacity(newCapacity);
951 setSize(newSize);
952 } else {
953 setSize(newSize);
954 recapacity(newCapacity);
955 }
956 } else {
957 setSize(newSize);
958 }
959 return *this;
960 }
961
962 /**
963 * Sets a new size for this instance.
964 * @param newSize new size, must be <= current capacity()
965 * @return
966 * @throws IllegalArgumentException if newSize > current capacity()
967 */
968 POctets & resize(const nsize_t newSize) {
969 if( _capacity < newSize ) {
970 throw IllegalArgumentError("capacity "+std::to_string(_capacity)+" < newSize "+std::to_string(newSize), E_FILE_LINE);
971 }
972 setSize(newSize);
973 return *this;
974 }
975
976 /**
977 * Changes the capacity.
978 *
979 * @param newCapacity new capacity, must be >= size()
980 * @return
981 * @throws OutOfMemoryError if allocation fails
982 * @throws IllegalArgumentException if newCapacity < size()
983 */
984 POctets & recapacity(const nsize_t newCapacity) {
985 if( newCapacity < size() ) {
986 throw IllegalArgumentError("newCapacity "+std::to_string(newCapacity)+" < size "+std::to_string(size()), E_FILE_LINE);
987 }
988 if( newCapacity == _capacity ) {
989 return *this;
990 }
991 uint8_t* data2 = allocData(newCapacity);
992 if( size() > 0 ) {
993 memcpy(data2, get_ptr(), size());
994 }
995 JAU_TRACE_OCTETS_PRINT("POctets recapacity: %p -> %p", data(), data2);
996 free(data());
997 setData(data2, size(), byte_order());
998 _capacity = newCapacity;
999 return *this;
1000 }
1001
1002 /**
1003 * Append and assign operator
1004 * @param b
1005 * @return
1006 * @throws OutOfMemoryError if allocation due to potential recapacity() fails
1007 */
1009 if( 0 < b.size() ) {
1010 const nsize_t newSize = size() + b.size();
1011 if( _capacity < newSize ) {
1012 recapacity( newSize );
1013 }
1014 memcpy(data()+size(), b.get_ptr(), b.size());
1015 setSize(newSize);
1016 }
1017 return *this;
1018 }
1019 /**
1020 * Append and assign operator
1021 * @param b
1022 * @return
1023 * @throws OutOfMemoryError if allocation due to potential recapacity() fails
1024 */
1026 if( 0 < b.size() ) {
1027 const nsize_t newSize = size() + b.size();
1028 if( _capacity < newSize ) {
1029 recapacity( newSize );
1030 }
1031 memcpy(data()+size(), b.parent().get_ptr()+b.offset(), b.size());
1032 setSize(newSize);
1033 }
1034 return *this;
1035 }
1036
1037 std::string toString() const noexcept {
1038 return string_noexcept([&](){ return "size "+std::to_string(size())+", capacity "+std::to_string(capacity())+", "+toHexString(get_ptr(), size()); } );
1039 }
1040 };
1041
1042 /**
1043 * Persistent endian aware octet data, i.e. owned automatic fixed size memory allocation.
1044 *
1045 * Endian byte order is passed at construction.
1046 *
1047 * Constructor and assignment operations are **not** completely `noexcept` and may throw exceptions.
1048 * This is a design choice based on dynamic resource allocation performed by this class.
1049 */
1050 template<jau::nsize_t FixedSize>
1051 class AOctets : public TOctets
1052 {
1053 public:
1054 /** Fixed maximum size */
1055 constexpr static const jau::nsize_t fixed_size = FixedSize;
1056
1057 private:
1058 uint8_t smem[fixed_size];
1059
1060 public:
1061 /**
1062 * Sized AOctets instance.
1063 *
1064 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
1065 */
1067 : TOctets(smem, fixed_size, byte_order)
1068 {
1069 JAU_TRACE_OCTETS_PRINT("AOctets ctor0: sized");
1070 }
1071
1072 /**
1073 * Takes ownership (malloc(size) and copy, free) ..
1074 *
1075 * Capacity and size will be of given source size.
1076 *
1077 * @param source_ source data to be copied into this new instance
1078 * @param size_ length of source data
1079 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
1080 * @throws IllegalArgumentException if fixed_size < source_size_
1081 * @throws IllegalArgumentException if source_ is nullptr and size_ > 0
1082 */
1083 AOctets(const uint8_t *source_, const nsize_t source_size_, const lb_endian_t byte_order)
1084 : TOctets( smem, std::min(fixed_size, source_size_), byte_order)
1085 {
1086 if( source_size_ > fixed_size ) {
1087 throw IllegalArgumentError("source size "+std::to_string(source_size_)+" > capacity "+std::to_string(fixed_size), E_FILE_LINE);
1088 } else if( 0 < source_size_ ) {
1089 if( nullptr == source_ ) {
1090 throw IllegalArgumentError("source nullptr with size "+std::to_string(source_size_)+" > 0", E_FILE_LINE);
1091 }
1092 std::memcpy(data(), source_, source_size_);
1093 }
1094 JAU_TRACE_OCTETS_PRINT("AOctets ctor1: %p", data());
1095 }
1096
1097 /**
1098 * Takes ownership (malloc(size) and copy, free) ..
1099 *
1100 * Capacity and size will be of given source size.
1101 *
1102 * @param sourcelist source initializer list data to be copied into this new instance with implied size
1103 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
1104 * @throws IllegalArgumentException if fixed_size < source size
1105 */
1106 AOctets(std::initializer_list<uint8_t> sourcelist, const lb_endian_t byte_order)
1107 : TOctets( smem, std::min(fixed_size, sourcelist.size()), byte_order)
1108 {
1109 if( sourcelist.size() > fixed_size ) {
1110 throw IllegalArgumentError("source size "+std::to_string(sourcelist.size())+" > capacity "+std::to_string(fixed_size), E_FILE_LINE);
1111 } else if( 0 < sourcelist.size() ) {
1112 std::memcpy(data(), sourcelist.begin(), sourcelist.size());
1113 }
1114 JAU_TRACE_OCTETS_PRINT("AOctets ctor1: %p", data());
1115 }
1116
1117 /**
1118 * Copy constructor
1119 *
1120 * Capacity of this new instance will be of source.size() only.
1121 *
1122 * @param source POctet source to be copied
1123 * @throws IllegalArgumentException if fixed_size < source size
1124 */
1125 AOctets(const TROOctets &source)
1126 : TOctets( smem, std::min(fixed_size, source.size()), source.byte_order() )
1127 {
1128 if( source.size() > fixed_size ) {
1129 throw IllegalArgumentError("source size "+std::to_string(source.size())+" > capacity "+std::to_string(fixed_size), E_FILE_LINE);
1130 } else if( 0 < source.size() ) {
1131 std::memcpy(data(), source.get_ptr(), source.size());
1132 }
1133 JAU_TRACE_OCTETS_PRINT("AOctets ctor-cpy0: %p -> %p", source.get_ptr(), data());
1134 }
1135
1136 /**
1137 * Assignment operator
1138 * @param _source POctet source to be copied
1139 * @return
1140 * @throws IllegalArgumentException if fixed_size < source size
1141 */
1142 AOctets& operator=(const TROOctets &_source) {
1143 if( this == &_source ) {
1144 return *this;
1145 }
1146 if( _source.size() > fixed_size ) {
1147 throw IllegalArgumentError("source size "+std::to_string(_source.size())+" > capacity "+std::to_string(fixed_size), E_FILE_LINE);
1148 } else if( 0 < _source.size() ) {
1149 std::memcpy(smem, _source.get_ptr(), _source.size());
1150 }
1151 setData(smem, _source.size(), _source.byte_order());
1152 JAU_TRACE_OCTETS_PRINT("AOctets assign0: %p", data());
1153 return *this;
1154 }
1155
1156
1157 ~AOctets() noexcept override {
1158 setData(nullptr, 0, byte_order());
1159 }
1160
1161 /**
1162 * Sets a new size for this instance.
1163 * @param newSize new size, must be <= current capacity()
1164 * @return
1165 * @throws IllegalArgumentException if fixed_size < newSize
1166 */
1167 AOctets & resize(const nsize_t newSize) {
1168 if( fixed_size < newSize ) {
1169 throw IllegalArgumentError("capacity "+std::to_string(fixed_size)+" < newSize "+std::to_string(newSize), E_FILE_LINE);
1170 }
1171 setSize(newSize);
1172 return *this;
1173 }
1174
1175 std::string toString() const noexcept {
1176 return string_noexcept([&](){ return "size "+std::to_string(size())+", fixed_size "+std::to_string(fixed_size)+", "+toHexString(get_ptr(), size()); });
1177 }
1178 };
1179
1180 /**@}*/
1181
1182} /* namespace jau */
1183
1184
1185#endif /* JAU_OCTETS_HPP_ */
AOctets(const TROOctets &source)
Copy constructor.
Definition octets.hpp:1125
static constexpr const jau::nsize_t fixed_size
Fixed maximum size.
Definition octets.hpp:1055
~AOctets() noexcept override
Definition octets.hpp:1157
AOctets & operator=(const TROOctets &_source)
Assignment operator.
Definition octets.hpp:1142
AOctets(const lb_endian_t byte_order) noexcept
Sized AOctets instance.
Definition octets.hpp:1066
std::string toString() const noexcept
Definition octets.hpp:1175
AOctets & resize(const nsize_t newSize)
Sets a new size for this instance.
Definition octets.hpp:1167
AOctets(const uint8_t *source_, const nsize_t source_size_, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:1083
AOctets(std::initializer_list< uint8_t > sourcelist, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:1106
POctets & operator=(const TROOctets &_source)
Assignment operator for TROOctets.
Definition octets.hpp:896
POctets(POctets &&o) noexcept
Move constructor.
Definition octets.hpp:826
POctets & operator=(POctets &&o) noexcept
Move assignment operator.
Definition octets.hpp:860
POctets(const nsize_t capacity_, const nsize_t size_, const lb_endian_t byte_order)
New buffer (malloc(capacity), free)
Definition octets.hpp:766
POctets(const POctets &source)
Copy constructor.
Definition octets.hpp:798
POctets & operator=(const POctets &_source)
Assignment operator.
Definition octets.hpp:843
POctets(const nsize_t size, const lb_endian_t byte_order)
New buffer (malloc, free)
Definition octets.hpp:783
POctets(const TROOctets &_source)
Makes a persistent POctets by copying the data from TROOctets.
Definition octets.hpp:882
~POctets() noexcept override
Definition octets.hpp:871
POctets & resize(const nsize_t newCapacity, const nsize_t newSize)
Resizes this instance, including its capacity.
Definition octets.hpp:944
POctets & operator=(const TOctetSlice &_source)
Assignment operator for TOctetSlice.
Definition octets.hpp:927
POctets & operator+=(const TOctetSlice &b)
Append and assign operator.
Definition octets.hpp:1025
constexpr nsize_t remaining() const noexcept
Returns the remaining octets for put left, i.e.
Definition octets.hpp:601
POctets(const POctets &source, const nsize_t capacity_)
Copy constructor (explicit), allowing to set a higher capacity than source.size() in contrast to the ...
Definition octets.hpp:814
POctets(const nsize_t capacity_, std::initializer_list< uint8_t > sourcelist, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:724
POctets(std::string_view source_, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:702
std::string toString() const noexcept
Definition octets.hpp:1037
POctets & recapacity(const nsize_t newCapacity)
Changes the capacity.
Definition octets.hpp:984
constexpr nsize_t capacity() const noexcept
Returns the memory capacity, never zero, greater or equal size().
Definition octets.hpp:598
POctets(std::initializer_list< uint8_t > sourcelist, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:747
POctets & resize(const nsize_t newSize)
Sets a new size for this instance.
Definition octets.hpp:968
POctets(const lb_endian_t byte_order) noexcept
Zero sized POctets instance.
Definition octets.hpp:610
POctets(const nsize_t capacity_, std::string_view source_, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:680
POctets(const nsize_t capacity_, const uint8_t *source_, const nsize_t size_, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:629
POctets & operator+=(const TROOctets &b)
Append and assign operator.
Definition octets.hpp:1008
POctets(const TOctetSlice &_source)
Makes a persistent POctets by copying the data from TOctetSlice.
Definition octets.hpp:913
POctets(const uint8_t *source_, const nsize_t size_, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:656
Transient endian aware octet data slice, i.e.
Definition octets.hpp:502
std::string toString() const noexcept
Definition octets.hpp:553
uint8_t get_uint8(const nsize_t i) const
Definition octets.hpp:532
constexpr lb_endian_t byte_order() const noexcept
Returns byte order of this octet store.
Definition octets.hpp:526
constexpr nsize_t offset() const noexcept
Definition octets.hpp:529
constexpr nsize_t size() const noexcept
Definition octets.hpp:528
constexpr const TOctets & parent() const noexcept
Definition octets.hpp:530
uint16_t get_uint16(const nsize_t i) const
Definition octets.hpp:539
constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept
Definition octets.hpp:542
constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept
Definition octets.hpp:549
TOctetSlice(const TOctets &buffer_, const nsize_t offset_, const nsize_t size_)
Creates a view of a given TOctet with the specified offset_ and size_.
Definition octets.hpp:517
uint8_t const * get_ptr(const nsize_t i) const
Definition octets.hpp:546
constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept
Definition octets.hpp:535
Transient endian aware octet data, i.e.
Definition octets.hpp:309
constexpr void put_uint64_nc(const nsize_t i, const uint64_t &v) noexcept
Definition octets.hpp:374
void put_uint128(const nsize_t i, const uint128dp_t &v)
Definition octets.hpp:378
void put_octets_nc(const nsize_t i, const TROOctets &v, const nsize_t v_off, const nsize_t v_len) noexcept
Definition octets.hpp:414
void memset(const nsize_t i, const uint8_t c, const nsize_t byte_count)
Definition octets.hpp:435
void put_uint64(const nsize_t i, const uint64_t &v)
Definition octets.hpp:370
TOctets(TOctets &&o) noexcept=default
void put_eui48(const nsize_t i, const jau::io::net::EUI48 &v)
Definition octets.hpp:362
TOctets(uint8_t *source, const nsize_t len, const lb_endian_t byte_order) noexcept
Transient passthrough r/w memory, w/o ownership .
Definition octets.hpp:320
void memmove_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept
Definition octets.hpp:431
void put_eui48_nc(const nsize_t i, const jau::io::net::EUI48 &v) noexcept
Definition octets.hpp:366
std::string toString() const noexcept
Definition octets.hpp:491
TOctets & operator=(const TOctets &o) noexcept=default
constexpr void put_uint32_nc(const nsize_t i, const uint32_t v) noexcept
Definition octets.hpp:358
void put_octets_nc(const nsize_t i, const TROOctets &v) noexcept
Definition octets.hpp:406
void put_uint192(const nsize_t i, const uint192dp_t &v)
Definition octets.hpp:386
void bzero_nc(const nsize_t i, const nsize_t byte_count) noexcept
Definition octets.hpp:446
void put_bytes_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept
Definition octets.hpp:423
void put_string(const nsize_t i, const std::string &v, const nsize_t max_len, const bool includeEOS)
Definition octets.hpp:455
void put_octets(const nsize_t i, const TROOctets &v)
Definition octets.hpp:402
void bzero(const nsize_t i, const nsize_t byte_count)
Definition octets.hpp:442
TOctets(const TOctets &o) noexcept=default
void put_uint256(const nsize_t i, const uint256dp_t &v)
Definition octets.hpp:394
void bzero() noexcept
Definition octets.hpp:449
constexpr void put_uint256_nc(const nsize_t i, const uint256dp_t &v) noexcept
Definition octets.hpp:398
TOctets & operator=(TOctets &&o) noexcept=default
constexpr void put_uint128_nc(const nsize_t i, const uint128dp_t &v) noexcept
Definition octets.hpp:382
constexpr void put_uint16_nc(const nsize_t i, const uint16_t v) noexcept
Definition octets.hpp:350
~TOctets() noexcept override=default
constexpr void put_uint8_nc(const nsize_t i, const uint8_t v) noexcept
Definition octets.hpp:342
uint8_t * get_wptr() noexcept
Definition octets.hpp:481
void memset_nc(const nsize_t i, const uint8_t c, const nsize_t byte_count) noexcept
Definition octets.hpp:439
void put_uint32(const nsize_t i, const uint32_t v)
Definition octets.hpp:354
void put_octets(const nsize_t i, const TROOctets &v, const nsize_t v_off, const nsize_t v_len)
Definition octets.hpp:409
void put_string_nc(const nsize_t i, const std::string &v, const nsize_t max_len, const bool includeEOS) noexcept
Definition octets.hpp:464
constexpr void put_int8_nc(const nsize_t i, const int8_t v) noexcept
Definition octets.hpp:334
void memmove(const nsize_t i, const uint8_t *source, const nsize_t byte_count)
Definition octets.hpp:427
uint8_t * get_wptr(const nsize_t i)
Definition octets.hpp:483
void put_uint16(const nsize_t i, const uint16_t v)
Definition octets.hpp:346
void put_uuid(const nsize_t i, const uuid_t &v)
Definition octets.hpp:473
constexpr void put_uint192_nc(const nsize_t i, const uint192dp_t &v) noexcept
Definition octets.hpp:390
void put_bytes(const nsize_t i, const uint8_t *source, const nsize_t byte_count)
Definition octets.hpp:419
void put_uuid_nc(const nsize_t i, const uuid_t &v) noexcept
Definition octets.hpp:477
uint8_t * get_wptr_nc(const nsize_t i) noexcept
Definition octets.hpp:487
void put_int8(const nsize_t i, const int8_t v)
Definition octets.hpp:330
void put_uint8(const nsize_t i, const uint8_t v)
Definition octets.hpp:338
Transient read only and endian aware octet data, i.e.
Definition octets.hpp:67
uint32_t get_uint32(const nsize_t i) const
Definition octets.hpp:188
constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept
Definition octets.hpp:184
jau::io::net::EUI48 get_eui48(const nsize_t i) const
Definition octets.hpp:196
TROOctets & operator=(const TROOctets &o) noexcept=default
std::unique_ptr< const uuid_t > get_uuid(const nsize_t i, const uuid_t::TypeSize tsize) const
Definition octets.hpp:267
uuid128_t get_uuid128_nc(const nsize_t i) const noexcept
Definition octets.hpp:263
constexpr uint128dp_t get_uint128_nc(const nsize_t i) const noexcept
Definition octets.hpp:216
std::string toString() const noexcept
Definition octets.hpp:288
jau::io::net::EUI48 get_eui48_nc(const nsize_t i) const noexcept
Definition octets.hpp:200
constexpr lb_endian_t byte_order() const noexcept
Returns byte order of this octet store.
Definition octets.hpp:159
uint128dp_t get_uint128(const nsize_t i) const
Definition octets.hpp:212
std::string get_string(const nsize_t i) const
Assumes a null terminated string.
Definition octets.hpp:237
TROOctets(TROOctets &&o) noexcept=default
TROOctets() noexcept
Default constructor with nullptr memory, zero size and lb_endian::native byte order.
Definition octets.hpp:136
TROOctets(const uint8_t *source, const nsize_t len, const lb_endian_t byte_order_val) noexcept
Transient passthrough read-only memory, w/o ownership .
Definition octets.hpp:123
constexpr nsize_t size() const noexcept
Returns the used memory size for read and write operations, may be zero.
Definition octets.hpp:162
constexpr bool is_range_valid(const nsize_t i, const nsize_t count) const noexcept
Definition octets.hpp:154
bool operator==(const TROOctets &rhs) const noexcept
Definition octets.hpp:281
virtual ~TROOctets() noexcept=default
constexpr int8_t get_int8_nc(const nsize_t i) const noexcept
Definition octets.hpp:176
bool operator!=(const TROOctets &rhs) const noexcept
Definition octets.hpp:284
uuid16_t get_uuid16(const nsize_t i) const
Definition octets.hpp:252
uuid16_t get_uuid16_nc(const nsize_t i) const noexcept
Definition octets.hpp:255
static void checkPtr(uint8_t *data_, nsize_t size_) noexcept
Validates the given data_ and size_.
Definition octets.hpp:85
TROOctets(const TROOctets &o) noexcept=default
uint8_t const * get_ptr(const nsize_t i) const
Definition octets.hpp:273
uint16_t get_uint16(const nsize_t i) const
Definition octets.hpp:180
std::string get_string(const nsize_t i, const nsize_t length) const
Assumes a string with defined length, not necessarily null terminated.
Definition octets.hpp:247
uint8_t get_uint8(const nsize_t i) const
Definition octets.hpp:164
std::string get_string_nc(const nsize_t i) const noexcept
Assumes a null terminated string.
Definition octets.hpp:242
void check_range(const nsize_t i, const nsize_t count, const char *file, int line) const
Definition octets.hpp:148
TROOctets & operator=(TROOctets &&o) noexcept=default
void setData(uint8_t *data_, nsize_t size_, const lb_endian_t byte_order) noexcept
Internally sets the _size and _data fields after validation.
Definition octets.hpp:103
constexpr uint192dp_t get_uint192_nc(const nsize_t i) const noexcept
Definition octets.hpp:224
uint64_t get_uint64(const nsize_t i) const
Definition octets.hpp:204
constexpr uint256dp_t get_uint256_nc(const nsize_t i) const noexcept
Definition octets.hpp:232
int8_t get_int8(const nsize_t i) const
Definition octets.hpp:172
constexpr uint8_t * data() noexcept
Definition octets.hpp:92
uint256dp_t get_uint256(const nsize_t i) const
Definition octets.hpp:228
uint192dp_t get_uint192(const nsize_t i) const
Definition octets.hpp:220
constexpr uint32_t get_uint32_nc(const nsize_t i) const noexcept
Definition octets.hpp:192
constexpr uint64_t get_uint64_nc(const nsize_t i) const noexcept
Definition octets.hpp:208
constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept
Definition octets.hpp:168
constexpr uint8_t const * get_ptr() const noexcept
Definition octets.hpp:272
constexpr void setSize(nsize_t s) noexcept
Definition octets.hpp:111
uuid128_t get_uuid128(const nsize_t i) const
Definition octets.hpp:259
constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept
Definition octets.hpp:277
static constexpr jau::nsize_t number(const TypeSize rhs) noexcept
Definition uuid.hpp:64
virtual jau::nsize_t put(uint8_t *const buffer, lb_endian_t const le_or_be) const noexcept=0
TypeSize
Underlying integer value present octet count.
Definition uuid.hpp:61
jau::nsize_t getTypeSizeInt() const noexcept
Definition uuid.hpp:127
static std::unique_ptr< uuid_t > create(TypeSize const t, uint8_t const *const buffer, lb_endian_t const le_or_be)
Definition uuid.cpp:56
#define jau_ABORT(...)
Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line fu...
Definition debug.hpp:149
constexpr uint192dp_t get_uint192(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr uint128dp_t get_uint128(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr void put_uint256(uint8_t *buffer, const uint256dp_t &v) noexcept
See put_uint16() for reference.
constexpr uint16_t get_uint16(uint8_t const *buffer) noexcept
Returns a uint16_t value from the given byte address using packed_t to resolve a potential memory ali...
std::string_view to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
constexpr uint32_t get_uint32(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr void put_uint32(uint8_t *buffer, const uint32_t v) noexcept
See put_uint16() for reference.
constexpr uint256dp_t get_uint256(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr void put_uint192(uint8_t *buffer, const uint192dp_t &v) noexcept
See put_uint16() for reference.
lb_endian_t
Simplified reduced endian type only covering little- and big-endian.
constexpr void put_uint64(uint8_t *buffer, const uint64_t &v) noexcept
See put_uint16() for reference.
constexpr void put_uint16(uint8_t *buffer, const uint16_t v) noexcept
Put the given uint16_t value into the given byte address using packed_t to resolve a potential memory...
constexpr void put_uint128(uint8_t *buffer, const uint128dp_t &v) noexcept
See put_uint16() for reference.
constexpr uint64_t get_uint64(uint8_t const *buffer) noexcept
See get_uint16() for reference.
constexpr int8_t get_int8(uint8_t const *buffer) noexcept
@ native
Identifier for native platform type, one of the above.
#define E_FILE_LINE
bool do_noexcept(UnaryPredicate p) noexcept
No throw wrap for given unary predicate p action. Returns true for success (no exception),...
uint_bytes_t< sizeof(unsigned long int)> nsize_t
Natural 'size_t' alternative using uint<XX>_t with xx = sizeof(unsigned long int)*8 as its natural si...
Definition int_types.hpp:89
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
uuid128_t get_uuid128(uint8_t const *buffer) noexcept
Definition uuid.hpp:263
void zero_bytes_sec(void *s, size_t n) noexcept __attrdecl_no_optimize__
Wrapper to ::explicit_bzero(), ::bzero() or ::memset(), whichever is available in that order.
std::string string_noexcept(UnaryPredicate p) noexcept
No throw wrap for given unary predicate p producing a std::string. Returns an empty string if p cause...
std::string & appendHexString(std::string &dest, const void *data, const nsize_t length, const lb_endian_t byteOrder=lb_endian_t::big, const LoUpCase capitalization=LoUpCase::lower, const PrefixOpt prefix=PrefixOpt::prefix) noexcept
Appends a hexadecimal string representation of the given lsb-first byte values.
std::string toHexString(const void *data, const nsize_t length, const lb_endian_t byteOrder=lb_endian_t::big, const LoUpCase capitalization=LoUpCase::lower, const PrefixOpt prefix=PrefixOpt::prefix) noexcept
Produce a hexadecimal string representation of the given lsb-first byte values.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
STL namespace.
#define JAU_TRACE_OCTETS_PRINT(...)
Definition octets.hpp:48
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
Definition eui48.hpp:322
jau::nsize_t put(uint8_t *const sink, const lb_endian_t byte_order) const noexcept
Definition eui48.cpp:244
A 128-bit packed uint8_t data array.
A 196-bit packed uint8_t data array.
A 256-bit packed uint8_t data array.