Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 : : * Author: Thun Lu <thun.lu@zohomail.cn>
4 : : * Repo: https://github.com/thun-res/vlink
5 : : * _ __ __ _ __
6 : : * | | / / / / (_) ____ / /__
7 : : * | | / / / / / / / __ \ / //_/
8 : : * | |/ / / /___ / / / / / / / ,<
9 : : * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 : : *
11 : : * Licensed under the Apache License, Version 2.0 (the "License");
12 : : * you may not use this file except in compliance with the License.
13 : : * You may obtain a copy of the License at
14 : : *
15 : : * http://www.apache.org/licenses/LICENSE-2.0
16 : : *
17 : : * Unless required by applicable law or agreed to in writing, software
18 : : * distributed under the License is distributed on an "AS IS" BASIS,
19 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 : : * See the License for the specific language governing permissions and
21 : : * limitations under the License.
22 : : */
23 : :
24 : : #include "./impl/types.h"
25 : :
26 : : #include <charconv>
27 : : #include <sstream>
28 : : #include <string>
29 : :
30 : : namespace vlink {
31 : :
32 : : // SampleLostInfo
33 : 3 : std::ostream& operator<<(std::ostream& ostream, const SampleLostInfo& info) noexcept {
34 : : ostream << "SampleLostInfo:"
35 : 3 : << "[total]" << info.total << "[lost]" << info.lost;
36 : :
37 : 3 : return ostream;
38 : : }
39 : :
40 : : // SchemaData
41 : 2546 : bool SchemaData::is_valid_type(SchemaType schema_type) noexcept {
42 [ + - ]: 2546 : switch (schema_type) {
43 : 2546 : case SchemaType::kUnknown:
44 : : case SchemaType::kProtobuf:
45 : : case SchemaType::kFlatbuffers:
46 : : case SchemaType::kRaw:
47 : : case SchemaType::kZeroCopy:
48 : 2546 : return true;
49 : : default: // LCOV_EXCL_LINE GCOVR_EXCL_LINE
50 : : return false; // LCOV_EXCL_LINE GCOVR_EXCL_LINE
51 : : }
52 : : }
53 : :
54 : 97 : bool SchemaData::is_real_type(SchemaType schema_type) noexcept {
55 [ + + ]: 97 : switch (schema_type) {
56 : 86 : case SchemaType::kProtobuf:
57 : : case SchemaType::kFlatbuffers:
58 : : case SchemaType::kZeroCopy:
59 : 86 : return true;
60 : 11 : default:
61 : 11 : return false;
62 : : }
63 : : }
64 : :
65 : 1559 : std::string_view SchemaData::convert_type(SchemaType schema_type) noexcept {
66 [ + + + - : 1559 : switch (schema_type) {
+ ]
67 : 456 : case SchemaType::kProtobuf:
68 : 456 : return "protobuf";
69 : 3 : case SchemaType::kFlatbuffers:
70 : 3 : return "flatbuffers";
71 : 974 : case SchemaType::kRaw:
72 : 974 : return "raw";
73 : 0 : case SchemaType::kZeroCopy:
74 : 0 : return "zerocopy";
75 : 126 : default:
76 : 126 : return "";
77 : : }
78 : : }
79 : :
80 : 886 : SchemaType SchemaData::convert_encoding(std::string_view encoding) noexcept {
81 : 678 : constexpr auto kIsAsciiSpace = [](char ch) noexcept {
82 [ + - + - : 678 : return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\f' || ch == '\v';
+ - + - +
- - + ]
83 : : };
84 : :
85 : 3550 : constexpr auto kAsciiLower = [](char ch) noexcept {
86 [ + - - + ]: 3550 : return ch >= 'A' && ch <= 'Z' ? static_cast<char>(ch - 'A' + 'a') : ch;
87 : : };
88 : :
89 : 10539 : const auto iequals = [kAsciiLower](std::string_view lhs, std::string_view rhs) noexcept {
90 [ + + ]: 10539 : if (lhs.size() != rhs.size()) {
91 : 9968 : return false;
92 : : }
93 : :
94 [ + + ]: 2108 : for (size_t i = 0; i < lhs.size(); ++i) {
95 [ + + ]: 1775 : if (kAsciiLower(lhs[i]) != kAsciiLower(rhs[i])) {
96 : 238 : return false;
97 : : }
98 : : }
99 : :
100 : 333 : return true;
101 : : };
102 : :
103 [ + + - + : 886 : while (!encoding.empty() && kIsAsciiSpace(encoding.front())) {
- + ]
104 : 0 : encoding.remove_prefix(1);
105 : : }
106 : :
107 [ + + - + : 886 : while (!encoding.empty() && kIsAsciiSpace(encoding.back())) {
- + ]
108 : 0 : encoding.remove_suffix(1);
109 : : }
110 : :
111 [ + + - + : 886 : if (iequals(encoding, "protobuf") || iequals(encoding, "proto")) {
+ + ]
112 : 107 : return SchemaType::kProtobuf;
113 : : }
114 : :
115 [ + - + - : 1558 : if (iequals(encoding, "flatbuffers") || iequals(encoding, "flatbuffer") || iequals(encoding, "fbs") ||
+ - + + ]
116 [ + + ]: 1558 : iequals(encoding, "bfbs")) {
117 : 1 : return SchemaType::kFlatbuffers;
118 : : }
119 : :
120 [ + + + - : 778 : if (iequals(encoding, "raw") || iequals(encoding, "json") || iequals(encoding, "text") || iequals(encoding, "blob")) {
+ - + + +
+ ]
121 : 225 : return SchemaType::kRaw;
122 : : }
123 : :
124 [ + - + - : 1106 : if (iequals(encoding, "string") || iequals(encoding, "std::string") || iequals(encoding, "application/json") ||
+ - - + ]
125 [ - + ]: 1106 : iequals(encoding, "text/json")) {
126 : 0 : return SchemaType::kRaw;
127 : : }
128 : :
129 [ + - - + : 553 : if (iequals(encoding, "zerocopy") || iequals(encoding, "vlink_msg")) {
- + ]
130 : 0 : return SchemaType::kZeroCopy;
131 : : }
132 : :
133 : 553 : return SchemaType::kUnknown;
134 : : }
135 : :
136 : 2213 : SchemaType SchemaData::resolve_type(SchemaType schema_type, std::string_view ser_type,
137 : : std::string_view encoding) noexcept {
138 [ + - ]: 2213 : const auto normalized_schema_type = is_valid_type(schema_type) ? schema_type : SchemaType::kUnknown;
139 : :
140 [ + + ]: 2213 : if (normalized_schema_type != SchemaType::kUnknown) {
141 : 1653 : return normalized_schema_type;
142 : : }
143 : :
144 : 560 : const auto inferred_encoding_type = convert_encoding(encoding);
145 : :
146 [ + + ]: 560 : if (inferred_encoding_type != SchemaType::kUnknown) {
147 : 49 : return inferred_encoding_type;
148 : : }
149 : :
150 : 511 : return infer_ser_type(ser_type);
151 : : }
152 : :
153 : : // Version
154 : 978 : bool Version::operator==(const Version& target) const noexcept {
155 [ + + + - : 978 : return major == target.major && minor == target.minor && patch == target.patch;
+ + ]
156 : : }
157 : :
158 : 976 : bool Version::operator!=(const Version& target) const noexcept { return !(*this == target); }
159 : :
160 : 15 : bool Version::operator<(const Version& target) const noexcept {
161 [ + + ]: 15 : if (major != target.major) {
162 : 6 : return major < target.major;
163 : : }
164 : :
165 [ + + ]: 9 : if (minor != target.minor) {
166 : 3 : return minor < target.minor;
167 : : }
168 : :
169 : 6 : return patch < target.patch;
170 : : }
171 : :
172 : 3 : bool Version::operator>(const Version& target) const noexcept { return target < *this; }
173 : :
174 : 111 : Version Version::from_string(const std::string& version_str) noexcept {
175 : 111 : Version version;
176 : :
177 [ + + ]: 111 : thread_local std::stringstream ss;
178 : 111 : ss.clear();
179 : 111 : ss.str(version_str);
180 : :
181 : 111 : std::string token;
182 : :
183 [ + + ]: 111 : if (std::getline(ss, token, '.')) {
184 : 110 : const auto* end = token.data() + token.size();
185 : 110 : auto result = std::from_chars(token.data(), end, version.major);
186 [ + + ]: 110 : if VUNLIKELY (result.ptr != end) {
187 : 1 : version.major = -1;
188 : : }
189 : : }
190 : :
191 [ + + ]: 111 : if (std::getline(ss, token, '.')) {
192 : 108 : const auto* end = token.data() + token.size();
193 : 108 : auto result = std::from_chars(token.data(), end, version.minor);
194 [ - + ]: 108 : if VUNLIKELY (result.ptr != end) {
195 : 0 : version.minor = -1;
196 : : }
197 : : }
198 : :
199 [ + + ]: 111 : if (std::getline(ss, token, '.')) {
200 : 107 : const auto* end = token.data() + token.size();
201 : 107 : auto result = std::from_chars(token.data(), end, version.patch);
202 [ - + ]: 107 : if VUNLIKELY (result.ptr != end) {
203 : 0 : version.patch = -1;
204 : : }
205 : : }
206 : :
207 : 222 : return version;
208 : 111 : }
209 : :
210 : 44 : std::string Version::to_string() const noexcept {
211 : 44 : return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch);
212 : : }
213 : :
214 [ + + + + : 95 : bool Version::is_valid() const noexcept { return major >= 0 && minor >= 0 && patch >= 0; }
+ + ]
215 : :
216 : : } // namespace vlink
|