jaulib v1.3.6
Jau Support Library (C++, Java, ..)
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-2024 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
35#include <jau/basic_types.hpp>
36#include <jau/debug.hpp>
37#include <jau/eui48.hpp>
38#include <jau/secmem.hpp>
39#include <jau/uuid.hpp>
40
41// #define JAU_TRACE_OCTETS 1
42#ifdef JAU_TRACE_OCTETS
43 #define JAU_TRACE_OCTETS_PRINT(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); }
44#else
45 #define JAU_TRACE_OCTETS_PRINT(...)
46#endif
47
48namespace jau {
49
50 /** \addtogroup ByteUtils
51 *
52 * @{
53 */
54
55 /**
56 * Transient read only and endian aware octet data, i.e. non persistent passthrough, owned by caller.
57 *
58 * Endian byte order is passed at construction.
59 *
60 * Constructor and assignment operations are `noexcept`. In case invalid arguments are passed, abort() is being called.
61 * This is a design choice based on reusing already existing underlying resources.
62 */
64 {
65 private:
66 /** Used memory size <= capacity, maybe zero. */
67 nsize_t _size;
68 /** Memory pointer, might be nullptr. Actual capacity known by owner, e.g. POctets. */
69 uint8_t * _data;
70 /** byte-order flag, little or big endian */
71 lb_endian_t _byte_order;
72
73 protected:
74 /**
75 * Validates the given data_ and size_.
76 *
77 * Aborts if data_ is nullptr and size_ > 0.
78 *
79 * @param data_ a memory pointer
80 * @param size_ claimed memory size
81 */
82 static inline void checkPtr(uint8_t *data_, nsize_t size_) noexcept {
83 if( nullptr == data_ && 0 < size_ ) {
84 ABORT("TROOctets: nullptr with size %s > 0", std::to_string(size_).c_str());
85 abort(); // never reached
86 }
87 }
88
89 constexpr uint8_t * data() noexcept { return _data; }
90
91 /**
92 * Internally sets the _size and _data fields after validation.
93 *
94 * Aborts if data_ is nullptr and size_ > 0.
95 *
96 * @param data_ a memory pointer
97 * @param size_ used memory size
98 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
99 */
100 inline void setData(uint8_t *data_, nsize_t size_, const lb_endian_t byte_order) noexcept {
101 JAU_TRACE_OCTETS_PRINT("POctets setData: %zu bytes @ %p -> %zu bytes @ %p",
102 _size, _data, size_, data_);
103 checkPtr(data_, size_);
104 _size = size_;
105 _data = data_;
106 _byte_order = byte_order;
107 }
108 constexpr void setSize(nsize_t s) noexcept { _size = s; }
109
110 public:
111 /**
112 * Transient passthrough read-only memory, w/o ownership ..
113 *
114 * Aborts if source is nullptr and len > 0.
115 *
116 * @param source a non nullptr memory, otherwise throws exception. Actual capacity known by owner.
117 * @param len readable size of the memory, may be zero
118 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
119 */
120 TROOctets(const uint8_t *source, const nsize_t len, const lb_endian_t byte_order_val ) noexcept
121 : _size( len ), _data( const_cast<uint8_t *>(source) ),
122 _byte_order( byte_order_val )
123 {
124 checkPtr(_data, _size);
125 }
126
127 /**
128 * Default constructor with nullptr memory, zero size and lb_endian::native byte order.
129 *
130 * Conveniently exists to allow instantiation of variables
131 * intended for later assignment.
132 */
133 TROOctets() noexcept
134 : _size( 0 ), _data( nullptr ),
135 _byte_order( lb_endian_t::native )
136 { }
137
138 TROOctets(const TROOctets &o) noexcept = default;
139 TROOctets(TROOctets &&o) noexcept = default;
140 TROOctets& operator=(const TROOctets &o) noexcept = default;
141 TROOctets& operator=(TROOctets &&o) noexcept = default;
142
143 virtual ~TROOctets() noexcept = default;
144
145 inline void check_range(const nsize_t i, const nsize_t count, const char *file, int line) const {
146 if( i+count > _size ) {
147 throw IndexOutOfBoundsError(i, count, _size, file, line);
148 }
149 }
150
151 constexpr bool is_range_valid(const nsize_t i, const nsize_t count) const noexcept {
152 return i+count <= _size;
153 }
154
155 /** Returns byte order of this octet store. */
156 constexpr lb_endian_t byte_order() const noexcept { return _byte_order; }
157
158 /** Returns the used memory size for read and write operations, may be zero. */
159 constexpr nsize_t size() const noexcept { return _size; }
160
161 uint8_t get_uint8(const nsize_t i) const {
163 return _data[i];
164 }
165 constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept {
166 return _data[i];
167 }
168
169 int8_t get_int8(const nsize_t i) const {
171 return jau::get_int8(_data + i);
172 }
173 constexpr int8_t get_int8_nc(const nsize_t i) const noexcept {
174 return jau::get_int8(_data + i);
175 }
176
177 uint16_t get_uint16(const nsize_t i) const {
179 return jau::get_uint16(_data + i, byte_order());
180 }
181 constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept {
182 return jau::get_uint16(_data + i, byte_order());
183 }
184
185 uint32_t get_uint32(const nsize_t i) const {
187 return jau::get_uint32(_data + i, byte_order());
188 }
189 constexpr uint32_t get_uint32_nc(const nsize_t i) const noexcept {
190 return jau::get_uint32(_data + i, byte_order());
191 }
192
193 EUI48 get_eui48(const nsize_t i) const {
194 check_range(i, sizeof(EUI48), E_FILE_LINE);
195 return EUI48(_data+i, byte_order() );
196 }
197 inline EUI48 get_eui48_nc(const nsize_t i) const noexcept {
198 return EUI48(_data+i, byte_order() );
199 }
200
201 uint64_t get_uint64(const nsize_t i) const {
203 return jau::get_uint64(_data + i, byte_order());
204 }
205 constexpr uint64_t get_uint64_nc(const nsize_t i) const noexcept {
206 return jau::get_uint64(_data + i, byte_order());
207 }
208
211 return jau::get_uint128(_data + i, byte_order());
212 }
213 constexpr uint128dp_t get_uint128_nc(const nsize_t i) const noexcept {
214 return jau::get_uint128(_data + i, byte_order());
215 }
216
219 return jau::get_uint192(_data + i, byte_order());
220 }
221 constexpr uint192dp_t get_uint192_nc(const nsize_t i) const noexcept {
222 return jau::get_uint192(_data + i, byte_order());
223 }
224
227 return jau::get_uint256(_data + i, byte_order());
228 }
229 constexpr uint256dp_t get_uint256_nc(const nsize_t i) const noexcept {
230 return jau::get_uint256(_data + i, byte_order());
231 }
232
233 /** Assumes a null terminated string */
234 std::string get_string(const nsize_t i) const {
235 check_range(i, 1, E_FILE_LINE); // minimum size
236 return std::string( (const char*)(_data+i) );
237 }
238 /** Assumes a null terminated string */
239 inline std::string get_string_nc(const nsize_t i) const noexcept {
240 return std::string( (const char*)(_data+i) );
241 }
242
243 /** Assumes a string with defined length, not necessarily null terminated */
244 std::string get_string(const nsize_t i, const nsize_t length) const {
245 check_range(i, length, E_FILE_LINE);
246 return std::string( (const char*)(_data+i), length );
247 }
248
249 uuid16_t get_uuid16(const nsize_t i) const {
250 return uuid16_t(get_uint16(i));
251 }
252 inline uuid16_t get_uuid16_nc(const nsize_t i) const noexcept {
253 return uuid16_t(get_uint16_nc(i));
254 }
255
260 inline uuid128_t get_uuid128_nc(const nsize_t i) const noexcept {
261 return jau::get_uuid128(_data + i, byte_order());
262 }
263
264 std::unique_ptr<const uuid_t> get_uuid(const nsize_t i, const uuid_t::TypeSize tsize) const {
266 return uuid_t::create(tsize, _data + i, byte_order());
267 }
268
269 constexpr uint8_t const * get_ptr() const noexcept { return _data; }
270 uint8_t const * get_ptr(const nsize_t i) const {
272 return _data + i;
273 }
274 constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept {
275 return _data + i;
276 }
277
278 bool operator==(const TROOctets& rhs) const noexcept {
279 return _size == rhs._size && 0 == std::memcmp(_data, rhs._data, _size);
280 }
281 bool operator!=(const TROOctets& rhs) const noexcept {
282 return !(*this == rhs);
283 }
284
285 std::string toString() const noexcept {
286 return "size "+std::to_string(_size)+", ["+to_string( byte_order() )+", "+to_string( byte_order() )+"], ro: "+bytesHexString(_data, 0, _size, true /* lsbFirst */);
287 }
288 };
289
290 /**
291 * Transient endian aware octet data, i.e. non persistent passthrough, owned by caller.
292 *
293 * Endian byte order is passed at construction.
294 *
295 * Constructor and assignment operations are `noexcept`. In case invalid arguments are passed, abort() is being called.
296 * This is a design choice based on reusing already existing underlying resources.
297 */
298 class TOctets : public TROOctets
299 {
300 public:
301 /**
302 * Transient passthrough r/w memory, w/o ownership ..
303 *
304 * Aborts if source is nullptr and len > 0.
305 *
306 * @param source transient data source
307 * @param len length of transient data source
308 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
309 */
310 TOctets(uint8_t *source, const nsize_t len, const lb_endian_t byte_order) noexcept
311 : TROOctets(source, len, byte_order) {}
312
313 TOctets(const TOctets &o) noexcept = default;
314 TOctets(TOctets &&o) noexcept = default;
315 TOctets& operator=(const TOctets &o) noexcept = default;
316 TOctets& operator=(TOctets &&o) noexcept = default;
317
318 ~TOctets() noexcept override = default;
319
320 void put_int8(const nsize_t i, const int8_t v) {
322 data()[i] = static_cast<uint8_t>(v);
323 }
324 constexpr void put_int8_nc(const nsize_t i, const int8_t v) noexcept {
325 data()[i] = static_cast<uint8_t>(v);
326 }
327
328 void put_uint8(const nsize_t i, const uint8_t v) {
330 data()[i] = v;
331 }
332 constexpr void put_uint8_nc(const nsize_t i, const uint8_t v) noexcept {
333 data()[i] = v;
334 }
335
336 void put_uint16(const nsize_t i, const uint16_t v) {
338 jau::put_uint16(data() + i, v, byte_order());
339 }
340 constexpr void put_uint16_nc(const nsize_t i, const uint16_t v) noexcept {
341 jau::put_uint16(data() + i, v, byte_order());
342 }
343
344 void put_uint32(const nsize_t i, const uint32_t v) {
346 jau::put_uint32(data() + i, v, byte_order());
347 }
348 constexpr void put_uint32_nc(const nsize_t i, const uint32_t v) noexcept {
349 jau::put_uint32(data() + i, v, byte_order());
350 }
351
352 void put_eui48(const nsize_t i, const EUI48 & v) {
353 check_range(i, sizeof(v.b), E_FILE_LINE);
354 v.put(data() + i, byte_order() );
355 }
356 inline void put_eui48_nc(const nsize_t i, const EUI48 & v) noexcept {
357 v.put(data() + i, byte_order() );
358 }
359
360 void put_uint64(const nsize_t i, const uint64_t & v) {
362 jau::put_uint64(data() + i, v, byte_order());
363 }
364 constexpr void put_uint64_nc(const nsize_t i, const uint64_t & v) noexcept {
365 jau::put_uint64(data() + i, v, byte_order());
366 }
367
368 void put_uint128(const nsize_t i, const uint128dp_t & v) {
370 jau::put_uint128(data() + i, v, byte_order());
371 }
372 constexpr void put_uint128_nc(const nsize_t i, const uint128dp_t & v) noexcept {
373 jau::put_uint128(data() + i, v, byte_order());
374 }
375
376 void put_uint192(const nsize_t i, const uint192dp_t & v) {
378 jau::put_uint192(data() + i, v, byte_order());
379 }
380 constexpr void put_uint192_nc(const nsize_t i, const uint192dp_t & v) noexcept {
381 jau::put_uint192(data() + i, v, byte_order());
382 }
383
384 void put_uint256(const nsize_t i, const uint256dp_t & v) {
386 jau::put_uint256(data() + i, v, byte_order());
387 }
388 constexpr void put_uint256_nc(const nsize_t i, const uint256dp_t & v) noexcept {
389 jau::put_uint256(data() + i, v, byte_order());
390 }
391
392 void put_octets(const nsize_t i, const TROOctets & v) {
394 std::memcpy(data() + i, v.get_ptr(), v.size());
395 }
396 void put_octets_nc(const nsize_t i, const TROOctets & v) noexcept {
397 std::memcpy(data() + i, v.get_ptr(), v.size());
398 }
399 void put_octets(const nsize_t i, const TROOctets & v, const nsize_t v_off, const nsize_t v_len) {
400 const nsize_t size = std::min(v.size()-v_off, v_len);
402 std::memcpy(data() + i, v.get_ptr() + v_off, size);
403 }
404 void put_octets_nc(const nsize_t i, const TROOctets & v, const nsize_t v_off, const nsize_t v_len) noexcept {
405 const nsize_t size = std::min(v.size()-v_off, v_len);
406 std::memcpy(data() + i, v.get_ptr() + v_off, size);
407 }
408
409 void put_bytes(const nsize_t i, const uint8_t *source, const nsize_t byte_count) {
410 check_range(i, byte_count, E_FILE_LINE);
411 std::memcpy(data() + i, source, byte_count);
412 }
413 void put_bytes_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept {
414 std::memcpy(data() + i, source, byte_count);
415 }
416
417 void memmove(const nsize_t i, const uint8_t *source, const nsize_t byte_count) {
418 check_range(i, byte_count, E_FILE_LINE);
419 std::memmove(data() + i, source, byte_count);
420 }
421 void memmove_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept {
422 std::memmove(data() + i, source, byte_count);
423 }
424
425 void memset(const nsize_t i, const uint8_t c, const nsize_t byte_count) {
426 check_range(i, byte_count, E_FILE_LINE);
427 std::memset(data() + i, c, byte_count);
428 }
429 void memset_nc(const nsize_t i, const uint8_t c, const nsize_t byte_count) noexcept {
430 std::memset(data() + i, c, byte_count);
431 }
432 void bzero(const nsize_t i, const nsize_t byte_count) {
433 check_range(i, byte_count, E_FILE_LINE);
434 zero_bytes_sec(data() + i, byte_count);
435 }
436 void bzero_nc(const nsize_t i, const nsize_t byte_count) noexcept {
437 zero_bytes_sec(data() + i, byte_count);
438 }
439 void bzero() noexcept {
440 if( size() > 0 ) {
442 }
443 }
444
445 void put_string(const nsize_t i, const std::string & v, const nsize_t max_len, const bool includeEOS) {
446 const nsize_t size1 = v.size() + ( includeEOS ? 1 : 0 );
447 const nsize_t size = std::min(size1, max_len);
449 std::memcpy(data() + i, v.c_str(), size);
450 if( size < size1 && includeEOS ) {
451 *(data() + i + size - 1) = 0; // ensure EOS
452 }
453 }
454 void put_string_nc(const nsize_t i, const std::string & v, const nsize_t max_len, const bool includeEOS) noexcept {
455 const nsize_t size1 = v.size() + ( includeEOS ? 1 : 0 );
456 const nsize_t size = std::min(size1, max_len);
457 std::memcpy(data() + i, v.c_str(), size);
458 if( size < size1 && includeEOS ) {
459 *(data() + i + size - 1) = 0; // ensure EOS
460 }
461 }
462
463 void put_uuid(const nsize_t i, const uuid_t & v) {
465 v.put(data() + i, byte_order());
466 }
467 void put_uuid_nc(const nsize_t i, const uuid_t & v) noexcept {
468 v.put(data() + i, byte_order());
469 }
470
471 inline uint8_t * get_wptr() noexcept { return data(); }
472
473 uint8_t * get_wptr(const nsize_t i) {
475 return data() + i;
476 }
477 inline uint8_t * get_wptr_nc(const nsize_t i) noexcept {
478 return data() + i;
479 }
480
481 std::string toString() const noexcept {
482 return "size "+std::to_string(size())+", rw: "+bytesHexString(get_ptr(), 0, size(), true /* lsbFirst */);
483 }
484 };
485
486 /**
487 * Transient endian aware octet data slice, i.e. a view of an TOctet.
488 *
489 * Endian byte order is defined by its parent TOctet.
490 */
492 {
493 private:
494 const TOctets & _parent;
495 nsize_t const _offset;
496 nsize_t const _size;
497
498 public:
499 /**
500 * Creates a view of a given TOctet with the specified offset_ and size_.
501 *
502 * @param buffer_ the parent TOctet buffer
503 * @param offset_ offset to the parent TOctet buffer
504 * @param size_ size of this view, starting at offset_
505 * @throws IndexOutOfBoundsException if offset_ + size_ > parent buffer_.size()
506 */
507 TOctetSlice(const TOctets &buffer_, const nsize_t offset_, const nsize_t size_)
508 : _parent(buffer_), _offset(offset_), _size(size_)
509 {
510 if( offset_+_size > buffer_.size() ) {
511 throw IndexOutOfBoundsError(offset_, _size, buffer_.size(), E_FILE_LINE);
512 }
513 }
514
515 /** Returns byte order of this octet store. */
516 constexpr lb_endian_t byte_order() const noexcept { return _parent.byte_order(); }
517
518 constexpr nsize_t size() const noexcept { return _size; }
519 constexpr nsize_t offset() const noexcept { return _offset; }
520 constexpr const TOctets& parent() const noexcept { return _parent; }
521
522 uint8_t get_uint8(const nsize_t i) const {
523 return _parent.get_uint8(_offset+i);
524 }
525 constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept {
526 return _parent.get_uint8_nc(_offset+i);
527 }
528
529 uint16_t get_uint16(const nsize_t i) const {
530 return _parent.get_uint16(_offset+i);
531 }
532 constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept {
533 return _parent.get_uint16_nc(_offset+i);
534 }
535
536 uint8_t const * get_ptr(const nsize_t i) const {
537 return _parent.get_ptr(_offset+i);
538 }
539 constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept {
540 return _parent.get_ptr_nc(_offset+i);
541 }
542
543 std::string toString() const noexcept {
544 return "offset "+std::to_string(_offset)+", size "+std::to_string(_size)+": "+bytesHexString(_parent.get_ptr(), _offset, _size, true /* lsbFirst */);
545 }
546 };
547
548 /**
549 * Persistent endian aware octet data, i.e. owned dynamic heap memory allocation.
550 *
551 * Endian byte order is passed at construction.
552 *
553 * Constructor and assignment operations are **not** completely `noexcept` and may throw exceptions.
554 * This is a design choice based on dynamic resource allocation performed by this class.
555 */
556 class POctets : public TOctets
557 {
558 private:
559 nsize_t _capacity;
560
561 void freeData() {
562 uint8_t * ptr = data();
563 if( nullptr != ptr ) {
564 JAU_TRACE_OCTETS_PRINT("POctets release: %p", ptr);
565 free(ptr);
566 } // else: zero sized POctets w/ nullptr are supported
567 }
568
569 /**
570 * Allocate a memory chunk.
571 * @param size
572 * @return
573 * @throws OutOfMemoryError if running out of memory
574 */
575 [[nodiscard]] static uint8_t * allocData(const nsize_t size) {
576 if( size <= 0 ) {
577 return nullptr;
578 }
579 uint8_t * m = static_cast<uint8_t*>( std::malloc(size) );
580 if( nullptr == m ) {
581 throw OutOfMemoryError("allocData size "+std::to_string(size)+" -> nullptr", E_FILE_LINE);
582 }
583 return m;
584 }
585
586 public:
587 /** Returns the memory capacity, never zero, greater or equal size(). */
588 constexpr nsize_t capacity() const noexcept { return _capacity; }
589
590 /** Returns the remaining octets for put left, i.e. capacity() - size(). */
591 constexpr nsize_t remaining() const noexcept { return _capacity - size(); }
592
593 /**
594 * Zero sized POctets instance.
595 *
596 * Will not throw an OutOfMemoryError exception due to no allocation.
597 *
598 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
599 */
601 : TOctets(nullptr, 0, byte_order), _capacity(0)
602 {
603 JAU_TRACE_OCTETS_PRINT("POctets ctor0: zero-sized");
604 }
605
606 /**
607 * Takes ownership (malloc(size) and copy, free) ..
608 *
609 * Capacity and size will be of given source size.
610 *
611 * @param source_ source data to be copied into this new instance
612 * @param size_ length of source data
613 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
614 * @throws IllegalArgumentException if source_ is nullptr and size_ > 0
615 * @throws OutOfMemoryError if allocation fails
616 */
617 POctets(const uint8_t *source_, const nsize_t size_, const lb_endian_t byte_order)
618 : TOctets( allocData(size_), size_, byte_order),
619 _capacity( size_ )
620 {
621 if( 0 < size_ ) {
622 if( nullptr == source_ ) {
623 throw IllegalArgumentError("source nullptr with size "+std::to_string(size_)+" > 0", E_FILE_LINE);
624 }
625 std::memcpy(data(), source_, size_);
626 }
627 JAU_TRACE_OCTETS_PRINT("POctets ctor1: %p", data());
628 }
629
630 /**
631 * Takes ownership (malloc(size) and copy, free) ..
632 *
633 * Capacity and size will be of given source size.
634 *
635 * @param sourcelist source initializer list data to be copied into this new instance with implied size
636 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
637 * @throws IllegalArgumentException if source_ is nullptr and size_ > 0
638 * @throws OutOfMemoryError if allocation fails
639 */
640 POctets(std::initializer_list<uint8_t> sourcelist, const lb_endian_t byte_order)
641 : TOctets( allocData(sourcelist.size()), sourcelist.size(), byte_order),
642 _capacity( sourcelist.size() )
643 {
644 if( 0 < _capacity ) {
645 std::memcpy(data(), sourcelist.begin(), _capacity);
646 }
647 JAU_TRACE_OCTETS_PRINT("POctets ctor1: %p", data());
648 }
649
650 /**
651 * New buffer (malloc(capacity), free)
652 *
653 * @param capacity_ new capacity
654 * @param size_ new size with size <= capacity
655 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
656 * @throws IllegalArgumentException if capacity_ < size_
657 * @throws OutOfMemoryError if allocation fails
658 */
659 POctets(const nsize_t capacity_, const nsize_t size_, const lb_endian_t byte_order)
660 : TOctets( allocData( capacity_ ), size_, byte_order ),
661 _capacity( capacity_ )
662 {
663 if( capacity() < size() ) {
664 throw IllegalArgumentError("capacity "+std::to_string(capacity())+" < size "+std::to_string(size()), E_FILE_LINE);
665 }
666 JAU_TRACE_OCTETS_PRINT("POctets ctor2: %p", data());
667 }
668
669 /**
670 * New buffer (malloc, free)
671 *
672 * @param size new size and capacity
673 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
674 * @throws OutOfMemoryError if allocation fails
675 */
678 {
679 JAU_TRACE_OCTETS_PRINT("POctets ctor3: %p", data());
680 }
681
682 /**
683 * Copy constructor
684 *
685 * Capacity of this new instance will be of source.size() only.
686 *
687 * @param source POctet source to be copied
688 * @throws OutOfMemoryError if allocation fails
689 */
690 POctets(const POctets &source)
691 : TOctets( allocData(source.size()), source.size(), source.byte_order() ),
692 _capacity( source.size() )
693 {
694 std::memcpy(data(), source.get_ptr(), source.size());
695 JAU_TRACE_OCTETS_PRINT("POctets ctor-cpy0: %p -> %p", source.get_ptr(), data());
696 }
697
698 /**
699 * Copy constructor (explicit), allowing to set a higher capacity
700 * than source.size() in contrast to the copy-constructor.
701 *
702 * @param source POctet source to be copied
703 * @param capacity_ used to determine new capacity `std::max(capacity_, source.size())`
704 * @throws OutOfMemoryError if allocation fails
705 */
706 explicit POctets(const POctets &source, const nsize_t capacity_)
707 : TOctets( allocData(source.size()), source.size(), source.byte_order() ),
708 _capacity( std::max(capacity_, source.size()) )
709 {
710 std::memcpy(data(), source.get_ptr(), source.size());
711 JAU_TRACE_OCTETS_PRINT("POctets ctor-cpy-extra1: %p -> %p", source.get_ptr(), data());
712 }
713
714 /**
715 * Move constructor
716 * @param o POctet source to be taken over
717 */
718 POctets(POctets &&o) noexcept
719 : TOctets( o.data(), o.size(), o.byte_order() ),
720 _capacity( o.capacity() )
721 {
722 // moved origin data references
723 // purge origin
724 o.setData(nullptr, 0, o.byte_order());
725 o._capacity = 0;
726 JAU_TRACE_OCTETS_PRINT("POctets ctor-move0: %p", data());
727 }
728
729 /**
730 * Assignment operator
731 * @param _source POctet source to be copied
732 * @return
733 * @throws OutOfMemoryError if allocation fails
734 */
735 POctets& operator=(const POctets &_source) {
736 if( this == &_source ) {
737 return *this;
738 }
739 freeData();
740 setData(allocData(_source.size()), _source.size(), _source.byte_order());
741 _capacity = _source.size();
742 std::memcpy(data(), _source.get_ptr(), _source.size());
743 JAU_TRACE_OCTETS_PRINT("POctets assign0: %p", data());
744 return *this;
745 }
746
747 /**
748 * Move assignment operator
749 * @param o POctet source to be taken over
750 * @return
751 */
752 POctets& operator=(POctets &&o) noexcept {
753 // move origin data references
754 setData(o.data(), o.size(), o.byte_order());
755 _capacity = o._capacity;
756 // purge origin
757 o.setData(nullptr, 0, o.byte_order());
758 o._capacity = 0;
759 JAU_TRACE_OCTETS_PRINT("POctets assign-move0: %p", data());
760 return *this;
761 }
762
763 ~POctets() noexcept override {
764 freeData();
765 setData(nullptr, 0, byte_order());
766 _capacity=0;
767 }
768
769 /**
770 * Makes a persistent POctets by copying the data from TROOctets.
771 * @param _source TROOctets to be copied
772 * @throws OutOfMemoryError if allocation fails
773 */
774 POctets(const TROOctets & _source)
775 : TOctets( allocData(_source.size()), _source.size(), _source.byte_order() ),
776 _capacity( _source.size() )
777 {
778 std::memcpy(data(), _source.get_ptr(), _source.size());
779 JAU_TRACE_OCTETS_PRINT("POctets ctor-cpy1: %p", data());
780 }
781
782 /**
783 * Assignment operator for TROOctets
784 * @param _source TROOctets to be copied
785 * @return
786 * @throws OutOfMemoryError if allocation fails
787 */
788 POctets& operator=(const TROOctets &_source) {
789 if( static_cast<TROOctets *>(this) == &_source ) {
790 return *this;
791 }
792 freeData();
793 setData(allocData(_source.size()), _source.size(), _source.byte_order());
794 _capacity = _source.size();
795 std::memcpy(data(), _source.get_ptr(), _source.size());
796 JAU_TRACE_OCTETS_PRINT("POctets assign1: %p", data());
797 return *this;
798 }
799
800 /**
801 * Makes a persistent POctets by copying the data from TOctetSlice.
802 * @param _source TROOctetSlice to be copied
803 * @throws OutOfMemoryError if allocation fails
804 */
805 POctets(const TOctetSlice & _source)
806 : TOctets( allocData(_source.size()), _source.size(), _source.byte_order() ),
807 _capacity( _source.size() )
808 {
809 std::memcpy(data(), _source.parent().get_ptr() + _source.offset(), _source.size());
810 JAU_TRACE_OCTETS_PRINT("POctets ctor-cpy2: %p", data());
811 }
812
813 /**
814 * Assignment operator for TOctetSlice
815 * @param _source TOctetSlice to be copied
816 * @return
817 * @throws OutOfMemoryError if allocation fails
818 */
819 POctets& operator=(const TOctetSlice &_source) {
820 freeData();
821 setData(allocData(_source.size()), _source.size(), _source.byte_order());
822 _capacity = _source.size();
823 std::memcpy(data(), _source.get_ptr(0), _source.size());
824 JAU_TRACE_OCTETS_PRINT("POctets assign2: %p", data());
825 return *this;
826 }
827
828 /**
829 * Resizes this instance, including its capacity
830 * @param newCapacity new capacity, must be >= newSize
831 * @param newSize new size, must be < newCapacity
832 * @return
833 * @throws OutOfMemoryError if allocation fails
834 * @throws IllegalArgumentException if newCapacity < newSize
835 */
836 POctets & resize(const nsize_t newCapacity, const nsize_t newSize) {
837 if( newCapacity < newSize ) {
838 throw IllegalArgumentError("newCapacity "+std::to_string(newCapacity)+" < newSize "+std::to_string(newSize), E_FILE_LINE);
839 }
840 if( newCapacity != _capacity ) {
841 if( newSize > size() ) {
842 recapacity(newCapacity);
843 setSize(newSize);
844 } else {
845 setSize(newSize);
846 recapacity(newCapacity);
847 }
848 } else {
849 setSize(newSize);
850 }
851 return *this;
852 }
853
854 /**
855 * Sets a new size for this instance.
856 * @param newSize new size, must be <= current capacity()
857 * @return
858 * @throws IllegalArgumentException if newSize > current capacity()
859 */
860 POctets & resize(const nsize_t newSize) {
861 if( _capacity < newSize ) {
862 throw IllegalArgumentError("capacity "+std::to_string(_capacity)+" < newSize "+std::to_string(newSize), E_FILE_LINE);
863 }
864 setSize(newSize);
865 return *this;
866 }
867
868 /**
869 * Changes the capacity.
870 *
871 * @param newCapacity new capacity, must be >= size()
872 * @return
873 * @throws OutOfMemoryError if allocation fails
874 * @throws IllegalArgumentException if newCapacity < size()
875 */
876 POctets & recapacity(const nsize_t newCapacity) {
877 if( newCapacity < size() ) {
878 throw IllegalArgumentError("newCapacity "+std::to_string(newCapacity)+" < size "+std::to_string(size()), E_FILE_LINE);
879 }
880 if( newCapacity == _capacity ) {
881 return *this;
882 }
883 uint8_t* data2 = allocData(newCapacity);
884 if( size() > 0 ) {
885 memcpy(data2, get_ptr(), size());
886 }
887 JAU_TRACE_OCTETS_PRINT("POctets recapacity: %p -> %p", data(), data2);
888 free(data());
889 setData(data2, size(), byte_order());
890 _capacity = newCapacity;
891 return *this;
892 }
893
894 /**
895 * Append and assign operator
896 * @param b
897 * @return
898 * @throws OutOfMemoryError if allocation due to potential recapacity() fails
899 */
901 if( 0 < b.size() ) {
902 const nsize_t newSize = size() + b.size();
903 if( _capacity < newSize ) {
904 recapacity( newSize );
905 }
906 memcpy(data()+size(), b.get_ptr(), b.size());
907 setSize(newSize);
908 }
909 return *this;
910 }
911 /**
912 * Append and assign operator
913 * @param b
914 * @return
915 * @throws OutOfMemoryError if allocation due to potential recapacity() fails
916 */
918 if( 0 < b.size() ) {
919 const nsize_t newSize = size() + b.size();
920 if( _capacity < newSize ) {
921 recapacity( newSize );
922 }
923 memcpy(data()+size(), b.parent().get_ptr()+b.offset(), b.size());
924 setSize(newSize);
925 }
926 return *this;
927 }
928
929 std::string toString() const {
930 return "size "+std::to_string(size())+", capacity "+std::to_string(capacity())+", "+bytesHexString(get_ptr(), 0, size(), true /* lsbFirst */);
931 }
932 };
933
934 /**
935 * Persistent endian aware octet data, i.e. owned automatic fixed size memory allocation.
936 *
937 * Endian byte order is passed at construction.
938 *
939 * Constructor and assignment operations are **not** completely `noexcept` and may throw exceptions.
940 * This is a design choice based on dynamic resource allocation performed by this class.
941 */
942 template<jau::nsize_t FixedSize>
943 class AOctets : public TOctets
944 {
945 public:
946 /** Fixed maximum size */
947 constexpr static const jau::nsize_t fixed_size = FixedSize;
948
949 private:
950 uint8_t smem[fixed_size];
951
952 public:
953 /**
954 * Sized AOctets instance.
955 *
956 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
957 */
960 {
961 JAU_TRACE_OCTETS_PRINT("AOctets ctor0: sized");
962 }
963
964 /**
965 * Takes ownership (malloc(size) and copy, free) ..
966 *
967 * Capacity and size will be of given source size.
968 *
969 * @param source_ source data to be copied into this new instance
970 * @param size_ length of source data
971 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
972 * @throws IllegalArgumentException if fixed_size < source_size_
973 * @throws IllegalArgumentException if source_ is nullptr and size_ > 0
974 */
975 AOctets(const uint8_t *source_, const nsize_t source_size_, const lb_endian_t byte_order)
976 : TOctets( smem, std::min(fixed_size, source_size_), byte_order)
977 {
978 if( source_size_ > fixed_size ) {
979 throw IllegalArgumentError("source size "+std::to_string(source_size_)+" > capacity "+std::to_string(fixed_size), E_FILE_LINE);
980 } else if( 0 < source_size_ ) {
981 if( nullptr == source_ ) {
982 throw IllegalArgumentError("source nullptr with size "+std::to_string(source_size_)+" > 0", E_FILE_LINE);
983 }
984 std::memcpy(data(), source_, source_size_);
985 }
986 JAU_TRACE_OCTETS_PRINT("AOctets ctor1: %p", data());
987 }
988
989 /**
990 * Takes ownership (malloc(size) and copy, free) ..
991 *
992 * Capacity and size will be of given source size.
993 *
994 * @param sourcelist source initializer list data to be copied into this new instance with implied size
995 * @param byte_order lb_endian::little or lb_endian::big byte order, one may pass lb_endian::native.
996 * @throws IllegalArgumentException if fixed_size < source size
997 */
998 AOctets(std::initializer_list<uint8_t> sourcelist, const lb_endian_t byte_order)
999 : TOctets( smem, std::min(fixed_size, sourcelist.size()), byte_order)
1000 {
1001 if( sourcelist.size() > fixed_size ) {
1002 throw IllegalArgumentError("source size "+std::to_string(sourcelist.size())+" > capacity "+std::to_string(fixed_size), E_FILE_LINE);
1003 } else if( 0 < sourcelist.size() ) {
1004 std::memcpy(data(), sourcelist.begin(), sourcelist.size());
1005 }
1006 JAU_TRACE_OCTETS_PRINT("AOctets ctor1: %p", data());
1007 }
1008
1009 /**
1010 * Copy constructor
1011 *
1012 * Capacity of this new instance will be of source.size() only.
1013 *
1014 * @param source POctet source to be copied
1015 * @throws IllegalArgumentException if fixed_size < source size
1016 */
1017 AOctets(const TROOctets &source)
1018 : TOctets( smem, std::min(fixed_size, source.size()), source.byte_order() )
1019 {
1020 if( source.size() > fixed_size ) {
1021 throw IllegalArgumentError("source size "+std::to_string(source.size())+" > capacity "+std::to_string(fixed_size), E_FILE_LINE);
1022 } else if( 0 < source.size() ) {
1023 std::memcpy(data(), source.get_ptr(), source.size());
1024 }
1025 JAU_TRACE_OCTETS_PRINT("AOctets ctor-cpy0: %p -> %p", source.get_ptr(), data());
1026 }
1027
1028 /**
1029 * Assignment operator
1030 * @param _source POctet source to be copied
1031 * @return
1032 * @throws IllegalArgumentException if fixed_size < source size
1033 */
1034 AOctets& operator=(const TROOctets &_source) {
1035 if( this == &_source ) {
1036 return *this;
1037 }
1038 if( _source.size() > fixed_size ) {
1039 throw IllegalArgumentError("source size "+std::to_string(_source.size())+" > capacity "+std::to_string(fixed_size), E_FILE_LINE);
1040 } else if( 0 < _source.size() ) {
1041 std::memcpy(smem, _source.get_ptr(), _source.size());
1042 }
1043 setData(smem, _source.size(), _source.byte_order());
1044 JAU_TRACE_OCTETS_PRINT("AOctets assign0: %p", data());
1045 return *this;
1046 }
1047
1048
1049 ~AOctets() noexcept override {
1050 setData(nullptr, 0, byte_order());
1051 }
1052
1053 /**
1054 * Sets a new size for this instance.
1055 * @param newSize new size, must be <= current capacity()
1056 * @return
1057 * @throws IllegalArgumentException if fixed_size < newSize
1058 */
1059 AOctets & resize(const nsize_t newSize) {
1060 if( fixed_size < newSize ) {
1061 throw IllegalArgumentError("capacity "+std::to_string(fixed_size)+" < newSize "+std::to_string(newSize), E_FILE_LINE);
1062 }
1063 setSize(newSize);
1064 return *this;
1065 }
1066
1067 std::string toString() const {
1068 return "size "+std::to_string(size())+", fixed_size "+std::to_string(fixed_size)+", "+bytesHexString(get_ptr(), 0, size(), true /* lsbFirst */);
1069 }
1070 };
1071
1072 /**@}*/
1073
1074} /* namespace jau */
1075
1076
1077#endif /* JAU_OCTETS_HPP_ */
#define E_FILE_LINE
AOctets(const TROOctets &source)
Copy constructor.
Definition octets.hpp:1017
static constexpr const jau::nsize_t fixed_size
Fixed maximum size.
Definition octets.hpp:947
~AOctets() noexcept override
Definition octets.hpp:1049
std::string toString() const
Definition octets.hpp:1067
AOctets & operator=(const TROOctets &_source)
Assignment operator.
Definition octets.hpp:1034
AOctets(const lb_endian_t byte_order) noexcept
Sized AOctets instance.
Definition octets.hpp:958
AOctets & resize(const nsize_t newSize)
Sets a new size for this instance.
Definition octets.hpp:1059
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:975
AOctets(std::initializer_list< uint8_t > sourcelist, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:998
POctets & operator=(const TROOctets &_source)
Assignment operator for TROOctets.
Definition octets.hpp:788
POctets(POctets &&o) noexcept
Move constructor.
Definition octets.hpp:718
POctets & operator=(POctets &&o) noexcept
Move assignment operator.
Definition octets.hpp:752
std::string toString() const
Definition octets.hpp:929
POctets(const nsize_t capacity_, const nsize_t size_, const lb_endian_t byte_order)
New buffer (malloc(capacity), free)
Definition octets.hpp:659
POctets(const POctets &source)
Copy constructor.
Definition octets.hpp:690
POctets & operator=(const POctets &_source)
Assignment operator.
Definition octets.hpp:735
POctets(const nsize_t size, const lb_endian_t byte_order)
New buffer (malloc, free)
Definition octets.hpp:676
POctets(const TROOctets &_source)
Makes a persistent POctets by copying the data from TROOctets.
Definition octets.hpp:774
~POctets() noexcept override
Definition octets.hpp:763
POctets & resize(const nsize_t newCapacity, const nsize_t newSize)
Resizes this instance, including its capacity.
Definition octets.hpp:836
POctets & operator=(const TOctetSlice &_source)
Assignment operator for TOctetSlice.
Definition octets.hpp:819
POctets & operator+=(const TOctetSlice &b)
Append and assign operator.
Definition octets.hpp:917
constexpr nsize_t remaining() const noexcept
Returns the remaining octets for put left, i.e.
Definition octets.hpp:591
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:706
POctets & recapacity(const nsize_t newCapacity)
Changes the capacity.
Definition octets.hpp:876
constexpr nsize_t capacity() const noexcept
Returns the memory capacity, never zero, greater or equal size().
Definition octets.hpp:588
POctets(std::initializer_list< uint8_t > sourcelist, const lb_endian_t byte_order)
Takes ownership (malloc(size) and copy, free) .
Definition octets.hpp:640
POctets & resize(const nsize_t newSize)
Sets a new size for this instance.
Definition octets.hpp:860
POctets(const lb_endian_t byte_order) noexcept
Zero sized POctets instance.
Definition octets.hpp:600
POctets & operator+=(const TROOctets &b)
Append and assign operator.
Definition octets.hpp:900
POctets(const TOctetSlice &_source)
Makes a persistent POctets by copying the data from TOctetSlice.
Definition octets.hpp:805
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:617
Transient endian aware octet data slice, i.e.
Definition octets.hpp:492
std::string toString() const noexcept
Definition octets.hpp:543
uint8_t get_uint8(const nsize_t i) const
Definition octets.hpp:522
constexpr lb_endian_t byte_order() const noexcept
Returns byte order of this octet store.
Definition octets.hpp:516
constexpr nsize_t offset() const noexcept
Definition octets.hpp:519
constexpr nsize_t size() const noexcept
Definition octets.hpp:518
constexpr const TOctets & parent() const noexcept
Definition octets.hpp:520
uint16_t get_uint16(const nsize_t i) const
Definition octets.hpp:529
constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept
Definition octets.hpp:532
constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept
Definition octets.hpp:539
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:507
uint8_t const * get_ptr(const nsize_t i) const
Definition octets.hpp:536
constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept
Definition octets.hpp:525
Transient endian aware octet data, i.e.
Definition octets.hpp:299
constexpr void put_uint64_nc(const nsize_t i, const uint64_t &v) noexcept
Definition octets.hpp:364
void put_uint128(const nsize_t i, const uint128dp_t &v)
Definition octets.hpp:368
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:404
void memset(const nsize_t i, const uint8_t c, const nsize_t byte_count)
Definition octets.hpp:425
void put_uint64(const nsize_t i, const uint64_t &v)
Definition octets.hpp:360
TOctets(TOctets &&o) noexcept=default
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:310
void memmove_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept
Definition octets.hpp:421
std::string toString() const noexcept
Definition octets.hpp:481
TOctets & operator=(const TOctets &o) noexcept=default
constexpr void put_uint32_nc(const nsize_t i, const uint32_t v) noexcept
Definition octets.hpp:348
void put_eui48(const nsize_t i, const EUI48 &v)
Definition octets.hpp:352
void put_octets_nc(const nsize_t i, const TROOctets &v) noexcept
Definition octets.hpp:396
void put_uint192(const nsize_t i, const uint192dp_t &v)
Definition octets.hpp:376
void bzero_nc(const nsize_t i, const nsize_t byte_count) noexcept
Definition octets.hpp:436
void put_bytes_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept
Definition octets.hpp:413
void put_string(const nsize_t i, const std::string &v, const nsize_t max_len, const bool includeEOS)
Definition octets.hpp:445
void put_octets(const nsize_t i, const TROOctets &v)
Definition octets.hpp:392
void bzero(const nsize_t i, const nsize_t byte_count)
Definition octets.hpp:432
TOctets(const TOctets &o) noexcept=default
void put_uint256(const nsize_t i, const uint256dp_t &v)
Definition octets.hpp:384
void bzero() noexcept
Definition octets.hpp:439
constexpr void put_uint256_nc(const nsize_t i, const uint256dp_t &v) noexcept
Definition octets.hpp:388
TOctets & operator=(TOctets &&o) noexcept=default
void put_eui48_nc(const nsize_t i, const EUI48 &v) noexcept
Definition octets.hpp:356
constexpr void put_uint128_nc(const nsize_t i, const uint128dp_t &v) noexcept
Definition octets.hpp:372
constexpr void put_uint16_nc(const nsize_t i, const uint16_t v) noexcept
Definition octets.hpp:340
~TOctets() noexcept override=default
constexpr void put_uint8_nc(const nsize_t i, const uint8_t v) noexcept
Definition octets.hpp:332
uint8_t * get_wptr() noexcept
Definition octets.hpp:471
void memset_nc(const nsize_t i, const uint8_t c, const nsize_t byte_count) noexcept
Definition octets.hpp:429
void put_uint32(const nsize_t i, const uint32_t v)
Definition octets.hpp:344
void put_octets(const nsize_t i, const TROOctets &v, const nsize_t v_off, const nsize_t v_len)
Definition octets.hpp:399
void put_string_nc(const nsize_t i, const std::string &v, const nsize_t max_len, const bool includeEOS) noexcept
Definition octets.hpp:454
constexpr void put_int8_nc(const nsize_t i, const int8_t v) noexcept
Definition octets.hpp:324
void memmove(const nsize_t i, const uint8_t *source, const nsize_t byte_count)
Definition octets.hpp:417
uint8_t * get_wptr(const nsize_t i)
Definition octets.hpp:473
void put_uint16(const nsize_t i, const uint16_t v)
Definition octets.hpp:336
void put_uuid(const nsize_t i, const uuid_t &v)
Definition octets.hpp:463
constexpr void put_uint192_nc(const nsize_t i, const uint192dp_t &v) noexcept
Definition octets.hpp:380
void put_bytes(const nsize_t i, const uint8_t *source, const nsize_t byte_count)
Definition octets.hpp:409
void put_uuid_nc(const nsize_t i, const uuid_t &v) noexcept
Definition octets.hpp:467
uint8_t * get_wptr_nc(const nsize_t i) noexcept
Definition octets.hpp:477
void put_int8(const nsize_t i, const int8_t v)
Definition octets.hpp:320
void put_uint8(const nsize_t i, const uint8_t v)
Definition octets.hpp:328
Transient read only and endian aware octet data, i.e.
Definition octets.hpp:64
uint32_t get_uint32(const nsize_t i) const
Definition octets.hpp:185
constexpr uint16_t get_uint16_nc(const nsize_t i) const noexcept
Definition octets.hpp:181
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:264
uuid128_t get_uuid128_nc(const nsize_t i) const noexcept
Definition octets.hpp:260
constexpr uint128dp_t get_uint128_nc(const nsize_t i) const noexcept
Definition octets.hpp:213
std::string toString() const noexcept
Definition octets.hpp:285
constexpr lb_endian_t byte_order() const noexcept
Returns byte order of this octet store.
Definition octets.hpp:156
uint128dp_t get_uint128(const nsize_t i) const
Definition octets.hpp:209
std::string get_string(const nsize_t i) const
Assumes a null terminated string.
Definition octets.hpp:234
TROOctets(TROOctets &&o) noexcept=default
TROOctets() noexcept
Default constructor with nullptr memory, zero size and lb_endian::native byte order.
Definition octets.hpp:133
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:120
constexpr nsize_t size() const noexcept
Returns the used memory size for read and write operations, may be zero.
Definition octets.hpp:159
constexpr bool is_range_valid(const nsize_t i, const nsize_t count) const noexcept
Definition octets.hpp:151
bool operator==(const TROOctets &rhs) const noexcept
Definition octets.hpp:278
virtual ~TROOctets() noexcept=default
constexpr int8_t get_int8_nc(const nsize_t i) const noexcept
Definition octets.hpp:173
bool operator!=(const TROOctets &rhs) const noexcept
Definition octets.hpp:281
uuid16_t get_uuid16(const nsize_t i) const
Definition octets.hpp:249
uuid16_t get_uuid16_nc(const nsize_t i) const noexcept
Definition octets.hpp:252
static void checkPtr(uint8_t *data_, nsize_t size_) noexcept
Validates the given data_ and size_.
Definition octets.hpp:82
TROOctets(const TROOctets &o) noexcept=default
uint8_t const * get_ptr(const nsize_t i) const
Definition octets.hpp:270
uint16_t get_uint16(const nsize_t i) const
Definition octets.hpp:177
EUI48 get_eui48_nc(const nsize_t i) const noexcept
Definition octets.hpp:197
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:244
uint8_t get_uint8(const nsize_t i) const
Definition octets.hpp:161
std::string get_string_nc(const nsize_t i) const noexcept
Assumes a null terminated string.
Definition octets.hpp:239
void check_range(const nsize_t i, const nsize_t count, const char *file, int line) const
Definition octets.hpp:145
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:100
constexpr uint192dp_t get_uint192_nc(const nsize_t i) const noexcept
Definition octets.hpp:221
uint64_t get_uint64(const nsize_t i) const
Definition octets.hpp:201
constexpr uint256dp_t get_uint256_nc(const nsize_t i) const noexcept
Definition octets.hpp:229
int8_t get_int8(const nsize_t i) const
Definition octets.hpp:169
constexpr uint8_t * data() noexcept
Definition octets.hpp:89
uint256dp_t get_uint256(const nsize_t i) const
Definition octets.hpp:225
uint192dp_t get_uint192(const nsize_t i) const
Definition octets.hpp:217
constexpr uint32_t get_uint32_nc(const nsize_t i) const noexcept
Definition octets.hpp:189
constexpr uint64_t get_uint64_nc(const nsize_t i) const noexcept
Definition octets.hpp:205
constexpr uint8_t get_uint8_nc(const nsize_t i) const noexcept
Definition octets.hpp:165
constexpr uint8_t const * get_ptr() const noexcept
Definition octets.hpp:269
constexpr void setSize(nsize_t s) noexcept
Definition octets.hpp:108
uuid128_t get_uuid128(const nsize_t i) const
Definition octets.hpp:256
constexpr uint8_t const * get_ptr_nc(const nsize_t i) const noexcept
Definition octets.hpp:274
EUI48 get_eui48(const nsize_t i) const
Definition octets.hpp:193
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 ABORT(...)
Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line fu...
Definition debug.hpp:101
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...
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.
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given 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.
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition int_types.hpp:55
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 bytesHexString(const void *data, const nsize_t length, const bool lsbFirst, const bool lowerCase=true, const bool skipLeading0x=false) noexcept
Produce a hexadecimal string representation of the given 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:45
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
Definition eui48.hpp:324
uint8_t b[6]
Definition eui48.hpp:324
jau::nsize_t put(uint8_t *const sink, const lb_endian_t byte_order) const noexcept
Definition eui48.cpp:242
A 128-bit packed uint8_t data array.
A 196-bit packed uint8_t data array.
A 256-bit packed uint8_t data array.