7#include <condition_variable>
16#include <nlohmann/json.hpp>
26#include <unordered_map>
53 static_assert(std::is_unsigned<T>::value,
54 "parseHex only supports unsigned integer types");
57 if constexpr (
sizeof(T) <=
sizeof(
unsigned long)) {
59 return static_cast<T
>(std::stoul(s,
nullptr, 16));
62 return static_cast<T
>(std::stoull(s,
nullptr, 16));
102T
toInteger(
const std::vector<std::uint8_t>& data, std::size_t offset = 0,
105 static_assert(std::is_integral<T>::value,
"T must be an integral type");
108 using U =
typename std::make_unsigned<T>::type;
113 std::size_t remaining = (data.size() > offset) ? (data.size() - offset) : 0;
114 std::size_t byteCount = (
sizeof(T) < remaining) ?
sizeof(T) : remaining;
117 for (std::size_t i = 0; i < byteCount; ++i) {
118 value |=
static_cast<U
>(data[offset + i]) << (8 * i);
121 for (std::size_t i = 0; i < byteCount; ++i) {
122 value |=
static_cast<U
>(data[offset + i]) << (8 * (
sizeof(T) - 1 - i));
126 return static_cast<T
>(
value);
137 const std::vector<uint8_t>& input,
size_t partSize);
157std::vector<uint8_t>
zipData(
const std::string& filename,
158 const std::vector<uint8_t>& data);
176std::unordered_map<std::string, std::vector<uint8_t>>
unzipData(
177 const std::vector<uint8_t>& data);
197 static_assert(std::is_arithmetic_v<T>,
"T must be an arithmetic type");
199 auto [ptr, ec] = std::from_chars(sv.data(), sv.data() + sv.size(), result);
200 return ec == std::errc();
220 static_assert(std::is_trivially_copyable<T>::value,
221 "T must be trivially copyable");
223 std::vector<uint8_t> bytes(
sizeof(T));
224 std::memcpy(bytes.data(), &
value,
sizeof(T));
227 std::reverse(bytes.begin(), bytes.end());
254T
fromBytes(
const std::vector<uint8_t>& bytes,
bool bigEndian =
false) {
255 static_assert(std::is_trivially_copyable<T>::value,
256 "T must be trivially copyable");
258 if (bytes.size() !=
sizeof(T)) {
259 throw std::invalid_argument(
260 "Byte vector size does not match target type size");
263 std::vector<uint8_t> temp = bytes;
266 std::reverse(temp.begin(), temp.end());
270 std::memcpy(&
value, temp.data(),
sizeof(T));
289 std::stringstream oss;
291 oss <<
"0x" << std::setw(4) << std::setfill(
'0') << std::hex << std::uppercase
292 <<
index <<
":" << std::setw(2) << std::setfill(
'0') << std::hex
293 << std::uppercase << subindex;
309inline std::string
toHex(
const std::vector<uint8_t>& data) {
310 std::ostringstream oss;
311 oss << std::uppercase;
312 for (
size_t i = 0; i < data.size(); ++i) {
313 oss <<
"0x" << std::hex << std::setw(2) << std::setfill(
'0')
314 <<
static_cast<int>(data[i]);
315 if (i != data.size() - 1) {
337 static_assert(std::is_integral<T>::value,
"toHex requires an integer type");
338 constexpr size_t hexWidth =
sizeof(T) * 2;
340 std::ostringstream oss;
341 oss <<
"0x" << std::hex << std::uppercase << std::setw(hexWidth)
342 << std::setfill(
'0') <<
static_cast<uint64_t
>(
value);
381std::string
joinStrings(
const std::vector<std::string>& list,
382 const std::string& delimiter);
422unsigned short extractPort(
const std::string& socketAddress);
431inline bool endsWith(
const std::string& str,
const std::string& suffix) {
432 return str.size() >= suffix.size() &&
433 std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
444 const std::string& prefix) {
445 return std::count_if(
446 strings.begin(), strings.end(), [&](
const std::string& s) {
447 return s.rfind(prefix, 0) == 0;
462inline std::vector<std::string>
split(
const std::string& input,
464 std::vector<std::string> result;
465 std::istringstream stream(input);
468 while (std::getline(stream, token, delimiter)) {
469 result.push_back(token);
487 std::queue<T> queue_;
490 mutable std::mutex mtx_;
493 std::condition_variable cv_;
518 std::lock_guard<std::mutex> lock(mtx_);
519 queue_.push(std::move(
value));
531 std::lock_guard<std::mutex> lock(mtx_);
532 if (queue_.empty())
return std::nullopt;
533 T
value = std::move(queue_.front());
546 std::unique_lock<std::mutex> lock(mtx_);
547 cv_.wait(lock, [
this] {
return !queue_.empty(); });
548 T
value = std::move(queue_.front());
559 std::lock_guard<std::mutex> lock(mtx_);
560 return queue_.empty();
571 std::lock_guard<std::mutex> lock(mtx_);
572 return queue_.size();
587 auto now = std::chrono::system_clock::now();
590 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(
591 now.time_since_epoch());
594 return duration.count();
610 static_assert(std::is_arithmetic<T>::value,
611 "linearScale requires a numeric type");
612 return outMin + (
value - inMin) * (outMax - outMin) / (inMax - inMin);
629struct hash<
std::pair<uint16_t, uint8_t>> {
640 size_t operator()(
const std::pair<uint16_t, uint8_t>& p)
const {
641 return hash<uint16_t>()(p.first) ^ (hash<uint8_t>()(p.second) << 1);
A simple thread-safe FIFO queue.
Definition: util.h:484
ThreadSafeQueue & operator=(const ThreadSafeQueue &)=delete
Deleted copy assignment operator.
T wait_and_pop()
Wait for an item to be available and pop it.
Definition: util.h:545
void push(T value)
Push a new value into the queue.
Definition: util.h:516
ThreadSafeQueue(const ThreadSafeQueue &)=delete
Deleted copy constructor.
bool empty() const
Check whether the queue is empty.
Definition: util.h:558
std::optional< T > try_pop()
Try to pop a value from the queue without blocking.
Definition: util.h:530
size_t size() const
Get the current number of items in the queue.
Definition: util.h:570
ThreadSafeQueue()=default
Construct a new empty ThreadSafeQueue.
uint8_t * value
Definition: co_dictionary.h:9
uint16_t index
Definition: co_dictionary.h:0
std::string joinStrings(const std::vector< std::string > &list, const std::string &delimiter)
Joins a list of strings into a single string with a delimiter.
Definition: util.cc:152
bool stringViewToNumber(std::string_view sv, T &result)
Converts a string_view to a numeric type.
Definition: util.h:196
std::vector< std::vector< uint8_t > > splitIntoParts(const std::vector< uint8_t > &input, size_t partSize)
Splits a byte vector into parts of a specified maximum size.
Definition: util.cc:13
int64_t currentTimeMillis()
Gets the current system time in milliseconds since the Unix epoch.
Definition: util.h:585
std::vector< uint8_t > zipData(const std::string &filename, const std::vector< uint8_t > &data)
Compresses a block of data into a ZIP archive containing a single file.
Definition: util.cc:31
Endianness
Specifies the byte order used when converting a byte sequence to an integer.
Definition: util.h:76
size_t countStringsStartingWith(const std::vector< std::string > &strings, const std::string &prefix)
Count how many strings in the list start with the given prefix.
Definition: util.h:443
T parseHex(const std::string &s)
Parses a hexadecimal string into an unsigned integer of type T.
Definition: util.h:52
std::string readTextFile(const std::string &filePath)
Reads the entire content of a text file into a std::string.
Definition: util.cc:138
unsigned short extractPort(const std::string &socketAddress)
Extracts the port number from a socket address string.
Definition: util.cc:199
bool endsWith(const std::string &str, const std::string &suffix)
Checks whether a string ends with the given suffix.
Definition: util.h:431
std::vector< std::string > split(const std::string &input, char delimiter)
Splits a string into substrings based on a delimiter character.
Definition: util.h:462
std::string extractIpAddress(const std::string &socketAddress)
Extracts the IP address from a socket address string.
Definition: util.cc:191
constexpr T linearScale(T value, T inMin, T inMax, T outMin, T outMax)
Definition: util.h:609
T fromBytes(const std::vector< uint8_t > &bytes, bool bigEndian=false)
Reconstructs a value of type T from a byte vector.
Definition: util.h:254
std::string toHex(const std::vector< uint8_t > &data)
Converts a vector of bytes to a space-separated hexadecimal string.
Definition: util.h:309
std::string formatMacAddress(const std::string &originalMacAddress)
Formats a MAC address string to ensure each component is two digits and uppercase.
Definition: util.cc:167
std::string makeParameterId(int index, int subindex)
Formats the given index and subindex into a parameter identifier string.
Definition: util.h:288
std::unordered_map< std::string, std::vector< uint8_t > > unzipData(const std::vector< uint8_t > &data)
Unzips a ZIP archive from an in-memory byte buffer.
Definition: util.cc:66
T toInteger(const std::vector< std::uint8_t > &data, std::size_t offset=0, Endianness endian=Endianness::LITTLE)
Converts a byte sequence to an integer of type T with optional offset and endianness.
Definition: util.h:102
std::vector< uint8_t > readBinaryFile(const std::string &filePath)
Reads the entire contents of a binary file into a byte vector.
Definition: util.cc:125
std::vector< uint8_t > toBytes(T value, bool bigEndian=false)
Converts a trivially copyable value to a byte vector.
Definition: util.h:219
Specialization of std::hash for std::pair<uint16_t, uint8_t>.
Definition: util.h:627
size_t operator()(const std::pair< uint16_t, uint8_t > &p) const
Computes a hash for a given std::pair<uint16_t, uint8_t>.
Definition: util.h:640