Files
slsDetectorPackage/slsSupportLib/include/sls/string_utils.h
T
Erik FröjdhandGitHub ffec82076d
Build and Deploy on local RHEL9 / build (push) Successful in 2m1s
Build on RHEL9 docker image / build (push) Successful in 4m31s
Build and Deploy on local RHEL8 / build (push) Successful in 5m6s
Build on RHEL8 docker image / build (push) Successful in 5m34s
Run Simulator Tests on local RHEL9 / build (push) Successful in 18m38s
Run Simulator Tests on local RHEL8 / build (push) Successful in 22m6s
Better error message on socket (#1477)
* checking errno

* improved socket error message

* improved message

* decode error code

* format

* clearer msg

* report write errors, handle SIGPIPE

* retry and cleaned up timeout

* removed read/write in DataSocket
2026-06-30 15:29:58 +02:00

102 lines
3.3 KiB
C++

// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include <cassert>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
namespace sls {
/* Implementation of a safe string copy function for setting fields in
for example the multi sls detector. It tries to copy the size of the
destination from the source, stopping on '\0'.
Warning this will truncate the source string and should be used with care.
Still this is better than strcpy and a buffer overflow...
*/
template <size_t array_size>
void strcpy_safe(char (&destination)[array_size], const char *source) {
assert(source != nullptr);
assert(array_size > strlen(source));
strncpy(destination, source, array_size - 1);
destination[array_size - 1] = '\0';
}
template <size_t array_size>
void strcpy_safe(char (&destination)[array_size], const std::string &source) {
assert(array_size > source.size());
strncpy(destination, source.c_str(), array_size - 1);
destination[array_size - 1] = '\0';
}
// Runtime-checked variant — throws if it won't fit
template <size_t array_size>
void strcpy_checked(char (&destination)[array_size], const char *source) {
if (!source)
throw std::runtime_error("Null source pointer in strcpy_checked");
size_t len = std::strlen(source);
if (len >= (array_size - 1)) {
throw std::runtime_error("String length (" + std::to_string(len) +
") should be less than " +
std::to_string(array_size - 1) + " chars");
}
std::strncpy(destination, source, array_size - 1);
destination[array_size - 1] = '\0';
}
template <size_t array_size>
void strcpy_checked(char (&destination)[array_size],
const std::string &source) {
if (source.size() >= (array_size - 1)) {
throw std::runtime_error("String length (" +
std::to_string(source.size()) +
") should be less than " +
std::to_string(array_size - 1) + " chars");
}
std::strncpy(destination, source.c_str(), array_size - 1);
destination[array_size - 1] = '\0';
}
/*
Removes all occurrences of the specified char from a c string
Templated on array size to ensure no access after buffer limits.
*/
template <size_t array_size> void removeChar(char (&str)[array_size], char ch) {
int count = 0;
for (int i = 0; str[i]; i++) {
if (str[i] != ch)
str[count++] = str[i];
if (i == array_size - 1)
break;
}
str[count] = '\0';
}
/*
Split a string using the specified delimeter and return a vector of strings.
TODO! Look into switching to absl or a string_view based implementation. Current
implementation should not be used in a performance critical place.
*/
std::vector<std::string> split(const std::string &strToSplit, char delimeter);
std::string RemoveUnit(std::string &str);
bool is_int(const std::string &s);
/** '0x200' is also an int here */
bool is_hex_or_dec_uint(const std::string &s);
bool replace_first(std::string *s, const std::string &substr,
const std::string &repl);
std::pair<std::string, uint16_t> ParseHostPort(const std::string &s);
std::string to_lower(const std::string &s);
} // namespace sls