jaulib v1.4.0-2-g788cf73
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
data_bitstream.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021-2025 Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11
12#include <cassert>
13#include <cstdint>
14#include <cstring>
15#include <string_view>
16#include <vector>
17
18#include <jau/basic_types.hpp>
19#include <jau/debug.hpp>
21#include <jau/string_util.hpp>
22
23using namespace jau::fractions_i64_literals;
24using namespace jau::int_literals;
25
26extern "C" {
27#include <unistd.h>
28}
29
31 public:
32 constexpr static uint32_t UNSIGNED_INT_MAX_VALUE = 0xffffffff_u32;
33
34 /**
35 * Returns the 32 bit mask of n-bits, i.e. n low order 1's.
36 * <p>
37 * Implementation handles n == 32.
38 * </p>
39 * @throws IndexOutOfBoundsError if {@code b} is out of bounds, i.e. &gt; 32
40 */
41 static uint32_t getBitMask(size_t n) {
42 if( 32 > n ) {
43 return ( 1_u32 << n ) - 1;
44 } else if ( 32 == n ) {
46 } else {
47 throw jau::IndexOutOfBoundsError("n <= 32 expected", n, 32, E_FILE_LINE);
48 }
49 }
50
51 inline const static std::vector<std::string_view> pyramid32bit_one = {
52 "00000000000000000000000000000001",
53 "00000000000000000000000000000010",
54 "00000000000000000000000000000100",
55 "00000000000000000000000000001000",
56 "00000000000000000000000000010000",
57 "00000000000000000000000000100000",
58 "00000000000000000000000001000000",
59 "00000000000000000000000010000000",
60 "00000000000000000000000100000000",
61 "00000000000000000000001000000000",
62 "00000000000000000000010000000000",
63 "00000000000000000000100000000000",
64 "00000000000000000001000000000000",
65 "00000000000000000010000000000000",
66 "00000000000000000100000000000000",
67 "00000000000000001000000000000000",
68 "00000000000000010000000000000000",
69 "00000000000000100000000000000000",
70 "00000000000001000000000000000000",
71 "00000000000010000000000000000000",
72 "00000000000100000000000000000000",
73 "00000000001000000000000000000000",
74 "00000000010000000000000000000000",
75 "00000000100000000000000000000000",
76 "00000001000000000000000000000000",
77 "00000010000000000000000000000000",
78 "00000100000000000000000000000000",
79 "00001000000000000000000000000000",
80 "00010000000000000000000000000000",
81 "00100000000000000000000000000000",
82 "01000000000000000000000000000000",
83 "10000000000000000000000000000000"
84 };
85
86 //
87 // MSB -> LSB over whole data, big-endian
88 //
89 constexpr static uint8_t testBytesMSB64_be[] = { 0xfa_u8, 0xde_u8, 0xaf_u8, 0xfe_u8, 0xde_u8, 0xaf_u8, 0xca_u8, 0xfe_u8 };
90 constexpr static uint64_t testIntMSB64_be = 0xfadeaffedeafcafe_u64;
91 // 11111010 11011110 10101111 11111110 11011110 10101111 11001010 11111110
92 constexpr static std::string_view testStringsMSB64_be[] = { "11111010", "11011110", "10101111", "11111110",
93 "11011110", "10101111", "11001010", "11111110" };
94 constexpr static std::string_view testStringMSB64_be = "11111010" "11011110" "10101111" "11111110"
95 "11011110" "10101111" "11001010" "11111110";
96
97 //
98 // MSB -> LSB, little-endian. Reverse byte-order of testBytesMSB64_be
99 //
100 constexpr static uint8_t testBytesMSB64_le[] = { 0xfe_u8, 0xca_u8, 0xaf_u8, 0xde_u8, 0xfe_u8, 0xaf_u8, 0xde_u8, 0xfa_u8 };
101 constexpr static uint64_t testIntMSB64_le = 0xfecaafdefeafdefa_u64;
102 // 11111110 11001010 10101111 11011110 11111110 10101111 11011110 11111010
103 constexpr static std::string_view testStringsMSB64_le[] = { "11111110", "11001010", "10101111", "11011110",
104 "11111110", "10101111", "11011110", "11111010" };
105
106 constexpr static std::string_view testStringMSB64_le = "11111110" "11001010" "10101111" "11011110"
107 "11111110" "10101111" "11011110" "11111010";
108 //
109 // LSB -> MSB over whole data, big-endian
110 //
111 constexpr static uint8_t testBytesLSB64_be[] = { 0x5F_u8, 0x7B_u8, 0xF5_u8, 0x7F_u8, 0x7B_u8, 0xF5_u8, 0x53_u8, 0x7F_u8 };
112 constexpr static uint64_t testIntLSB64_be = 0x5F7BF57F7BF5537F_u64;
113 // 01011111 01111011 11110101 01111111 01111011 11110101 01010011 01111111
114 constexpr static std::string_view testStringsLSB64_be[] = { "01011111", "01111011", "11110101", "01111111",
115 "01111011", "11110101", "01010011", "01111111" };
116 constexpr static std::string_view testStringLSB64_be = "01011111" "01111011" "11110101" "01111111"
117 "01111011" "11110101" "01010011" "01111111";
118 //
119 // LSB -> MSB, little endian. Reverse byte-order of testBytesLSB64_be and whole bit-reverse of testBytesMSB64_be
120 //
121 constexpr static uint8_t testBytesLSB64_le[] = { 0x7F_u8, 0x53_u8, 0xF5_u8, 0x7B_u8, 0x7F_u8, 0xF5_u8, 0x7B_u8, 0x5F_u8 };
122 constexpr static uint64_t testIntLSB64_le = 0x7F53F57B7FF57B5F_u64;
123 // 01111111 01010011 11110101 01111011 01111111 11110101 01111011 01011111
124 constexpr static std::string_view testStringsLSB64_le[] = { "01111111" "01010011" "11110101" "01111011"
125 "01111111" "11110101" "01111011" "01011111" };
126 constexpr static std::string_view testStringLSB64_le = "01111111" "01010011" "11110101" "01111011" "01111111" "11110101" "01111011" "01011111";
127
128 static void dumpData(const std::string& prefix, const uint8_t* data, size_t len) {
129 for( size_t i = 0; i < len; ) {
130 fprintf(stderr, "%s: %03zu: ", prefix.c_str(), i);
131 for( size_t j = 0; j < 8 && i < len; ++j, ++i ) {
132 const uint8_t v = 0xFF & data[i];
133 fprintf(stderr, "%s, ", toHexBinaryString(v, 8).c_str());
134 }
135 fprintf(stderr, "\n");
136 }
137 }
138 static void dumpData(const std::string& prefix, jau::io::ByteStream& data, size_t len) {
139 fprintf(stderr, "%s: Dump %s\n", prefix.c_str(), data.toString().c_str());
140 bool err = false;
141 size_t p = data.position();
142 for( size_t i = 0; i < len && !err; ) {
143 fprintf(stderr, "%s: %03zu: ", prefix.c_str(), i);
144 for( size_t j = 0; j < 8 && i < len && !err; ++j, ++i ) {
145 uint8_t v;
146 err = data.read(v);
147 fprintf(stderr, "%s, ", toHexBinaryString(v, 8).c_str());
148 }
149 fprintf(stderr, "\n");
150 }
151 if( p != data.seek(p) ) {
152 throw jau::RuntimeException("couldn't rewind stream to "+std::to_string(p)+": "+data.toString(), E_FILE_LINE);
153 }
154 }
155 static void dumpData(const std::string& prefix, jau::io::ByteStream& data) { dumpData(prefix, data, data.remaining()); }
156
157 static size_t getOneBitCount(std::string_view pattern) {
158 size_t c = 0;
159 for( size_t i = 0; i < pattern.length(); ++i ) {
160 if( '1' == pattern[i] ) {
161 ++c;
162 }
163 }
164 return c;
165 }
166 static uint64_t toLong(const std::string_view bitPattern) {
167 const auto [result, len, ok] = jau::fromBitString(bitPattern);
168 if (!ok) {
169 throw jau::RuntimeException("parse error: " + std::string(bitPattern), E_FILE_LINE);
170 }
171 return (uint64_t)result;
172 }
173 static uint64_t toInteger(const std::string_view bitPattern) {
174 const auto [result, len, ok] = jau::fromBitString(bitPattern);
175 if (!ok) {
176 throw jau::RuntimeException("parse error: " + std::string(bitPattern), E_FILE_LINE);
177 }
178 return result;
179 }
180
181 static std::string toHexString(const int v) {
182 return jau::toHexString(v);
183 }
184 static std::string toHexString(const int64_t v) {
185 return jau::toHexString(v);
186 }
187 static constexpr const char* strZeroPadding = "0000000000000000000000000000000000000000000000000000000000000000"; // 64
188 static std::string toBinaryString(const uint64_t v, const size_t bitCount) {
189 if( 0 == bitCount ) {
190 return "";
191 }
192 const std::string& s0 = jau::toBitString(v, jau::bit_order_t::msb, jau::PrefixOpt::none, bitCount);
193 // std::string padding(strZeroPadding, bitCount > s0.length() ? bitCount - s0.length() : 0);
194 // return padding + s0;
195 return s0;
196 }
197 static std::string toHexBinaryString(const uint64_t v, const int bitCount) {
198 return jau::toHexString(v) + " (" + toBinaryString(v, bitCount) + ")";
199 }
200};
#define E_FILE_LINE
static constexpr uint8_t testBytesLSB64_be[]
static constexpr std::string_view testStringsLSB64_be[]
static void dumpData(const std::string &prefix, jau::io::ByteStream &data)
static constexpr std::string_view testStringMSB64_le
static uint64_t toInteger(const std::string_view bitPattern)
static std::string toHexBinaryString(const uint64_t v, const int bitCount)
static uint64_t toLong(const std::string_view bitPattern)
static constexpr uint64_t testIntLSB64_le
static std::string toBinaryString(const uint64_t v, const size_t bitCount)
static constexpr uint8_t testBytesLSB64_le[]
static size_t getOneBitCount(std::string_view pattern)
static uint32_t getBitMask(size_t n)
Returns the 32 bit mask of n-bits, i.e.
static constexpr uint64_t testIntMSB64_le
static void dumpData(const std::string &prefix, jau::io::ByteStream &data, size_t len)
static constexpr std::string_view testStringsMSB64_le[]
static const std::vector< std::string_view > pyramid32bit_one
static constexpr const char * strZeroPadding
static void dumpData(const std::string &prefix, const uint8_t *data, size_t len)
static constexpr uint64_t testIntLSB64_be
static constexpr std::string_view testStringsLSB64_le[]
static constexpr std::string_view testStringsMSB64_be[]
static constexpr uint32_t UNSIGNED_INT_MAX_VALUE
static constexpr std::string_view testStringLSB64_be
static std::string toHexString(const int v)
static constexpr std::string_view testStringLSB64_le
static constexpr uint64_t testIntMSB64_be
static constexpr std::string_view testStringMSB64_be
static constexpr uint8_t testBytesMSB64_le[]
static constexpr uint8_t testBytesMSB64_be[]
static std::string toHexString(const int64_t v)
Byte stream interface.
virtual size_t read(void *out, size_t length) noexcept=0
Read from the source.
virtual std::string toString() const noexcept=0
virtual size_type position() const noexcept=0
Returns the position indicator, similar to e.g.
virtual size_type remaining() const noexcept
Returns the remaining bytes, i.e.
virtual size_type seek(size_type newPos) noexcept=0
Sets position indicator for output-streams or input-streams with known length, similar to e....
std::string toBitString(const void *data, const nsize_t length, const bit_order_t bitOrder=bit_order_t::msb, const PrefixOpt prefix=PrefixOpt::prefix, size_t bit_len=0) noexcept
Produce a binary string representation of the given lsb-first byte values.
SizeBoolPair fromBitString(std::vector< uint8_t > &out, const uint8_t bitstr[], const size_t bitstr_len, const bit_order_t bitOrder=bit_order_t::msb, const Bool checkPrefix=Bool::True) noexcept
Converts a given binary string representation into a byte vector, lsb-first.
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.
@ msb
Identifier for most-significant-bit (msb) first.