unilink  0.4.3
A simple C++ library for unified async communication
common.hpp
Go to the documentation of this file.
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
36 
37 namespace unilink {
38 namespace base {
39 
41 
42 // LCOV_EXCL_START
43 inline const char* to_cstr(LinkState s) {
44  switch (s) {
45  case LinkState::Idle:
46  return "Idle";
48  return "Connecting";
50  return "Listening";
52  return "Connected";
53  case LinkState::Closed:
54  return "Closed";
55  case LinkState::Error:
56  return "Error";
57  }
58  return "?";
59 }
60 
61 inline std::string ts_now() {
62  using namespace std::chrono;
63  const auto now = system_clock::now();
64  const auto tt = system_clock::to_time_t(now);
65  std::tm tm{};
66 #if defined(UNILINK_PLATFORM_WINDOWS)
67  localtime_s(&tm, &tt);
68 #else
69  localtime_r(&tt, &tm);
70 #endif
71  const auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
72  std::ostringstream oss;
73  oss << std::put_time(&tm, "%F %T") << '.' << std::setw(3) << std::setfill('0') << ms.count();
74  return oss.str(); // e.g., 2025-09-15 13:07:42.123
75 }
76 
77 inline void log_message(std::string_view tag, std::string_view direction, std::string_view message) {
78  // Remove trailing newline from message if it exists
79  std::string_view clean_message = message;
80  if (!clean_message.empty() && clean_message.back() == '\n') {
81  clean_message.remove_suffix(1);
82  }
83 
84  // Use new logging system
85  diagnostics::Logger::instance().info(tag, direction, clean_message);
86 }
87 
88 // Platform-specific feature availability
90 
92 
94 
96 
97 inline std::string get_platform_warning() { return PlatformInfo::get_support_warning(); }
98 // LCOV_EXCL_STOP
99 
100 // Safe memory operations
101 namespace safe_memory {
109 inline void safe_memcpy(uint8_t* dest, const uint8_t* src, size_t size) {
110  if (!dest) {
111  throw std::invalid_argument("Destination pointer is null");
112  }
113  if (!src) {
114  throw std::invalid_argument("Source pointer is null");
115  }
116  if (size == 0) {
117  return; // Nothing to copy
118  }
119  if (size > 1024 * 1024) { // 1MB limit
120  throw std::invalid_argument("Copy size too large (max 1MB)");
121  }
122 
123  std::memcpy(dest, src, size);
124 }
125 
133 inline void safe_memcpy(char* dest, const char* src, size_t size) {
134  safe_memcpy(reinterpret_cast<uint8_t*>(dest), reinterpret_cast<const uint8_t*>(src), size);
135 }
136 } // namespace safe_memory
137 
138 // Safe type conversion utilities
139 namespace safe_convert {
146 inline std::string uint8_to_string(const uint8_t* data, size_t size) {
147  if (!data || size == 0) {
148  return std::string{};
149  }
150  return std::string(data, data + size);
151 }
152 
159 inline std::vector<uint8_t> string_to_uint8(const char* data, size_t size) {
160  if (!data || size == 0) {
161  return std::vector<uint8_t>{};
162  }
163  return std::vector<uint8_t>(data, data + size);
164 }
165 
171 inline std::vector<uint8_t> string_to_uint8(std::string_view str) {
172  return std::vector<uint8_t>(str.begin(), str.end());
173 }
174 
180 inline std::pair<const uint8_t*, size_t> string_to_bytes(std::string_view str) {
181  return {reinterpret_cast<const uint8_t*>(str.data()), str.size()};
182 }
183 } // namespace safe_convert
184 
185 // Removed unused feed_lines function to eliminate -Wunused-function warning
186 } // namespace base
187 
188 // Compatibility alias while transitioning from legacy `common` namespace.
189 namespace common {
190 namespace safe_memory = base::safe_memory;
191 namespace safe_convert = base::safe_convert;
198 using base::log_message;
199 using base::to_cstr;
200 using base::ts_now;
201 } // namespace common
202 } // namespace unilink