ssp/include/ss/common.hpp

94 lines
2.2 KiB
C++
Raw Normal View History

#pragma once
#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
namespace ss {
struct none {};
using string_range = std::pair<const char*, const char*>;
using split_data = std::vector<string_range>;
constexpr inline auto default_delimiter = ",";
constexpr inline auto get_line_initial_buffer_size = 128;
template <bool StringError>
inline void assert_string_error_defined() {
static_assert(StringError,
"'string_error' needs to be enabled to use 'error_msg'");
}
template <bool ThrowOnError>
inline void assert_throw_on_error_not_defined() {
static_assert(!ThrowOnError, "cannot handle errors manually if "
"'throw_on_error' is enabled");
}
2021-02-21 22:25:58 +01:00
#if __unix__
inline ssize_t get_line_file(char** lineptr, size_t* n, FILE* stream) {
2021-02-21 22:25:58 +01:00
return getline(lineptr, n, stream);
}
#else
using ssize_t = intptr_t;
2021-02-21 22:22:18 +01:00
2024-02-23 02:49:13 +01:00
ssize_t get_line_file(char** lineptr, size_t* n, FILE* fp) {
if (lineptr == nullptr || n == nullptr || fp == nullptr) {
2021-02-21 22:22:18 +01:00
errno = EINVAL;
return -1;
}
char buff[get_line_initial_buffer_size];
2021-02-21 22:22:18 +01:00
if (*lineptr == nullptr || *n < sizeof(buff)) {
2024-02-23 00:59:58 +01:00
size_t new_n = sizeof(buff);
auto new_lineptr = static_cast<char*>(realloc(*lineptr, new_n));
if (new_lineptr == nullptr) {
errno = ENOMEM;
2021-02-21 22:22:18 +01:00
return -1;
}
*lineptr = new_lineptr;
2024-02-23 00:59:58 +01:00
*n = new_n;
2021-02-21 22:22:18 +01:00
}
(*lineptr)[0] = '\0';
size_t line_used = 0;
while (fgets(buff, sizeof(buff), fp) != nullptr) {
line_used = strlen(*lineptr);
size_t buff_used = strlen(buff);
if (*n <= buff_used + line_used) {
2024-02-23 00:59:58 +01:00
size_t new_n = *n * 2;
auto new_lineptr = static_cast<char*>(realloc(*lineptr, new_n));
if (new_lineptr == nullptr) {
errno = ENOMEM;
2021-02-21 22:22:18 +01:00
return -1;
}
*lineptr = new_lineptr;
2024-02-23 00:59:58 +01:00
*n = new_n;
2021-02-21 22:22:18 +01:00
}
memcpy(*lineptr + line_used, buff, buff_used);
line_used += buff_used;
(*lineptr)[line_used] = '\0';
if ((*lineptr)[line_used - 1] == '\n') {
return line_used;
2021-02-21 22:22:18 +01:00
}
}
return (line_used != 0) ? line_used : -1;
2021-02-21 22:22:18 +01:00
}
2021-02-21 22:22:18 +01:00
#endif
} /* ss */