Branch data Line data Source code
1 : : /*
2 : : * Copyright 2025 Jinwoo Sung
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #pragma once
18 : :
19 : : #include <chrono>
20 : : #include <cstdint>
21 : : #include <cstring>
22 : : #include <ctime>
23 : : #include <functional>
24 : : #include <iomanip>
25 : : #include <iostream>
26 : : #include <sstream>
27 : : #include <stdexcept>
28 : : #include <string>
29 : : #include <string_view>
30 : : #include <utility>
31 : : #include <vector>
32 : :
33 : : // Include logger for log_message function
34 : : #include "wirestead/base/constants.hpp"
35 : : #include "wirestead/base/platform.hpp"
36 : : #include "wirestead/diagnostics/logger.hpp"
37 : :
38 : : namespace wirestead {
39 : :
40 : : /**
41 : : * @brief Strong type alias for client identifiers
42 : : */
43 : : using ClientId = size_t;
44 : :
45 : : namespace base {
46 : :
47 : : enum class LinkState { Idle, Connecting, Listening, Connected, Closed, Error };
48 : :
49 : : // LCOV_EXCL_START
50 : : inline const char* to_cstr(LinkState s) {
51 : : switch (s) {
52 : : case LinkState::Idle:
53 : : return "Idle";
54 : : case LinkState::Connecting:
55 : : return "Connecting";
56 : : case LinkState::Listening:
57 : : return "Listening";
58 : : case LinkState::Connected:
59 : : return "Connected";
60 : : case LinkState::Closed:
61 : : return "Closed";
62 : : case LinkState::Error:
63 : : return "Error";
64 : : }
65 : : return "?";
66 : : }
67 : :
68 : : inline std::string ts_now() {
69 : : using namespace std::chrono;
70 : : const auto now = system_clock::now();
71 : : const auto tt = system_clock::to_time_t(now);
72 : : std::tm tm{};
73 : : #if defined(WIRESTEAD_PLATFORM_WINDOWS)
74 : : localtime_s(&tm, &tt);
75 : : #else
76 : : localtime_r(&tt, &tm);
77 : : #endif
78 : : const auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
79 : : std::ostringstream oss;
80 : : oss << std::put_time(&tm, "%F %T") << '.' << std::setw(3) << std::setfill('0') << ms.count();
81 : : return oss.str(); // e.g., 2025-09-15 13:07:42.123
82 : : }
83 : :
84 : : inline void log_message(std::string_view tag, std::string_view direction, std::string_view message) {
85 : : // Remove trailing newline from message if it exists
86 : : std::string_view clean_message = message;
87 : : if (!clean_message.empty() && clean_message.back() == '\n') {
88 : : clean_message.remove_suffix(1);
89 : : }
90 : :
91 : : // Use new logging system
92 : : diagnostics::Logger::instance().info(tag, direction, clean_message);
93 : : }
94 : :
95 : : // Platform-specific feature availability
96 : : inline bool is_advanced_logging_available() { return PlatformInfo::is_advanced_logging_available(); }
97 : :
98 : : inline bool is_performance_monitoring_available() { return PlatformInfo::is_performance_monitoring_available(); }
99 : :
100 : : inline bool is_latest_optimizations_available() { return PlatformInfo::is_latest_optimizations_available(); }
101 : :
102 : : inline bool is_experimental_features_available() { return PlatformInfo::is_experimental_features_available(); }
103 : :
104 : : inline std::string get_platform_warning() { return PlatformInfo::get_support_warning(); }
105 : : // LCOV_EXCL_STOP
106 : :
107 : : // Safe memory operations
108 : : namespace safe_memory {
109 : : /**
110 : : * @brief Safely copy memory with bounds checking
111 : : * @param dest Destination buffer
112 : : * @param src Source buffer
113 : : * @param size Number of bytes to copy
114 : : * @throws std::invalid_argument if parameters are invalid
115 : : */
116 : 1300 : inline void safe_memcpy(uint8_t* dest, const uint8_t* src, size_t size) {
117 [ + + ]: 1300 : if (!dest) {
118 : 1 : throw std::invalid_argument("Destination pointer is null");
119 : : }
120 [ + + ]: 1299 : if (!src) {
121 : 1 : throw std::invalid_argument("Source pointer is null");
122 : : }
123 [ + + ]: 1298 : if (size == 0) {
124 : 1 : return; // Nothing to copy
125 : : }
126 [ + + ]: 1297 : if (size > constants::MAX_BUFFER_SIZE) {
127 : 1 : throw std::invalid_argument("Copy size too large (max MAX_BUFFER_SIZE)");
128 : : }
129 : :
130 : 1296 : std::memcpy(dest, src, size);
131 : : }
132 : :
133 : : /**
134 : : * @brief Safely copy memory with bounds checking (overloaded for char*)
135 : : * @param dest Destination buffer
136 : : * @param src Source buffer
137 : : * @param size Number of bytes to copy
138 : : * @throws std::invalid_argument if parameters are invalid
139 : : */
140 : : inline void safe_memcpy(char* dest, const char* src, size_t size) {
141 : : safe_memcpy(reinterpret_cast<uint8_t*>(dest), reinterpret_cast<const uint8_t*>(src), size);
142 : : }
143 : : } // namespace safe_memory
144 : :
145 : : // Safe type conversion utilities
146 : : namespace safe_convert {
147 : : /**
148 : : * @brief Safely convert uint8_t* to const char* for string operations
149 : : * @param data Pointer to uint8_t data
150 : : * @param size Size of the data
151 : : * @return std::string constructed from the data
152 : : */
153 : 2 : inline std::string uint8_to_string(const uint8_t* data, size_t size) {
154 [ + + - + ]: 2 : if (!data || size == 0) {
155 : 1 : return std::string{};
156 : : }
157 : 2 : return std::string(data, data + size);
158 : : }
159 : :
160 : : /**
161 : : * @brief Safely convert const char* to const uint8_t* for binary operations
162 : : * @param data Pointer to char data
163 : : * @param size Size of the data
164 : : * @return std::vector<uint8_t> containing the data
165 : : */
166 : : inline std::vector<uint8_t> string_to_uint8(const char* data, size_t size) {
167 : : if (!data || size == 0) {
168 : : return std::vector<uint8_t>{};
169 : : }
170 : : return std::vector<uint8_t>(data, data + size);
171 : : }
172 : :
173 : : /**
174 : : * @brief Safely convert std::string to std::vector<uint8_t>
175 : : * @param str The string to convert
176 : : * @return std::vector<uint8_t> containing the string data
177 : : */
178 : 1 : inline std::vector<uint8_t> string_to_uint8(std::string_view str) {
179 : 2 : return std::vector<uint8_t>(str.begin(), str.end());
180 : : }
181 : :
182 : : /**
183 : : * @brief Safely obtain a view of std::string as byte array without allocation
184 : : * @param str The string to convert
185 : : * @return std::pair<const uint8_t*, size_t> containing pointer and size
186 : : */
187 : 3334 : inline std::pair<const uint8_t*, size_t> string_to_bytes(std::string_view str) {
188 : 3334 : return {reinterpret_cast<const uint8_t*>(str.data()), str.size()};
189 : : }
190 : : } // namespace safe_convert
191 : :
192 : : // Removed unused feed_lines function to eliminate -Wunused-function warning
193 : : } // namespace base
194 : :
195 : : } // namespace wirestead
|