8 #include "opentelemetry/common/kv_properties.h"
9 #include "opentelemetry/common/macros.h"
10 #include "opentelemetry/nostd/shared_ptr.h"
11 #include "opentelemetry/nostd/string_view.h"
12 #include "opentelemetry/version.h"
22 static constexpr
size_t kMaxKeyValuePairs = 180;
23 static constexpr
size_t kMaxKeyValueSize = 4096;
24 static constexpr
size_t kMaxSize = 8192;
25 static constexpr
char kKeyValueSeparator =
'=';
26 static constexpr
char kMembersSeparator =
',';
27 static constexpr
char kMetadataSeparator =
';';
29 Baggage() noexcept : kv_properties_(new
common::KeyValueProperties()) {}
33 Baggage(
const T &keys_and_values) noexcept
48 return kv_properties_->GetValue(key, value);
59 const bool valid_kv = IsValidKey(key) && IsValidValue(value);
63 baggage->kv_properties_->AddEntry(key, value);
67 kv_properties_->GetAllEntries(
71 if (!valid_kv || key != e_key)
73 baggage->kv_properties_->AddEntry(e_key, e_value);
87 return kv_properties_->GetAllEntries(callback);
98 kv_properties_->GetAllEntries(
101 baggage->kv_properties_->AddEntry(e_key, e_value);
110 if (header.size() > kMaxSize)
117 size_t cnt = kv_str_tokenizer.
NumTokens();
118 if (cnt > kMaxKeyValuePairs)
120 cnt = kMaxKeyValuePairs;
127 while (kv_str_tokenizer.
next(kv_valid, key, value) &&
baggage->kv_properties_->Size() < cnt)
129 if (!kv_valid || (key.
size() + value.
size() > kMaxKeyValueSize))
138 auto metadata_separator = value.
find(kMetadataSeparator);
139 if (metadata_separator != std::string::npos)
141 metadata = value.
substr(metadata_separator);
142 value = value.
substr(0, metadata_separator);
149 if (err ==
false && IsValidKey(key_str) && IsValidValue(value_str))
151 if (!metadata.
empty())
153 value_str.append(metadata.
data(), metadata.
size());
155 baggage->kv_properties_->AddEntry(key_str, value_str);
165 std::string header_s;
170 header_s.push_back(kMembersSeparator);
176 header_s.append(UrlEncode(key));
177 header_s.push_back(kKeyValueSeparator);
180 auto metadata_separator = value.
find(kMetadataSeparator);
181 if (metadata_separator != std::string::npos)
183 header_s.append(UrlEncode(value.
substr(0, metadata_separator)));
184 auto metadata = value.
substr(metadata_separator);
185 header_s.append(std::string(metadata.data(), metadata.size()));
189 header_s.append(UrlEncode(value));
199 for (
const auto ch : str)
201 if (ch < ' ' || ch >
'~')
212 static bool IsValidValue(
nostd::string_view value) {
return IsPrintableString(value); }
218 auto to_hex = [](
char c) ->
char {
219 static const char *hex =
"0123456789ABCDEF";
227 if (std::isalnum(c) || c ==
'-' || c ==
'_' || c ==
'.' || c ==
'~')
238 ret.push_back(to_hex(c >> 4));
239 ret.push_back(to_hex(c & 15));
249 auto IsHex = [](
char c) {
250 return std::isdigit(c) || (c >=
'A' && c <=
'F') || (c >=
'a' && c <=
'f');
253 auto from_hex = [](
char c) ->
char {
256 return static_cast<char>(std::isdigit(c) ? c -
'0' : std::toupper(c) -
'A' + 10);
261 for (
size_t i = 0; i < str.
size(); i++)
265 if (i + 2 >= str.
size() || !IsHex(str[i + 1]) || !IsHex(str[i + 2]))
270 ret.push_back(from_hex(str[i + 1]) << 4 | from_hex(str[i + 2]));
273 else if (str[i] ==
'+')
277 else if (std::isalnum(str[i]) || str[i] ==
'-' || str[i] ==
'_' || str[i] ==
'.' ||
280 ret.push_back(str[i]);