]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/common/kv_properties.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / api / include / opentelemetry / common / kv_properties.h
CommitLineData
1e59de90
TL
1// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include "opentelemetry/common/key_value_iterable_view.h"
7#include "opentelemetry/common/string_util.h"
8#include "opentelemetry/nostd/function_ref.h"
9#include "opentelemetry/nostd/shared_ptr.h"
10#include "opentelemetry/nostd/string_view.h"
11#include "opentelemetry/nostd/unique_ptr.h"
12#include "opentelemetry/version.h"
13
14#include <cstring>
15#include <string>
16#include <type_traits>
17
18OPENTELEMETRY_BEGIN_NAMESPACE
19namespace common
20{
21
22// Constructor parameter for KeyValueStringTokenizer
23struct KeyValueStringTokenizerOptions
24{
25 char member_separator = ',';
26 char key_value_separator = '=';
27 bool ignore_empty_members = true;
28};
29
30// Tokenizer for key-value headers
31class KeyValueStringTokenizer
32{
33public:
34 KeyValueStringTokenizer(
35 nostd::string_view str,
36 const KeyValueStringTokenizerOptions &opts = KeyValueStringTokenizerOptions()) noexcept
37 : str_(str), opts_(opts), index_(0)
38 {}
39
40 static nostd::string_view GetDefaultKeyOrValue()
41 {
42 static std::string default_str = "";
43 return default_str;
44 }
45
46 // Returns next key value in the string header
47 // @param valid_kv : if the found kv pair is valid or not
48 // @param key : key in kv pair
49 // @param key : value in kv pair
50 // @returns true if next kv pair was found, false otherwise.
51 bool next(bool &valid_kv, nostd::string_view &key, nostd::string_view &value) noexcept
52 {
53 valid_kv = true;
54 while (index_ < str_.size())
55 {
56 bool is_empty_pair = false;
57 size_t end = str_.find(opts_.member_separator, index_);
58 if (end == std::string::npos)
59 {
60 end = str_.size() - 1;
61 }
62 else if (end == index_) // empty pair. do not update end
63 {
64 is_empty_pair = true;
65 }
66 else
67 {
68 end--;
69 }
70
71 auto list_member = StringUtil::Trim(str_, index_, end);
72 if (list_member.size() == 0 || is_empty_pair)
73 {
74 // empty list member
75 index_ = end + 2 - is_empty_pair;
76 if (opts_.ignore_empty_members)
77 {
78 continue;
79 }
80
81 valid_kv = true;
82 key = GetDefaultKeyOrValue();
83 value = GetDefaultKeyOrValue();
84 return true;
85 }
86
87 auto key_end_pos = list_member.find(opts_.key_value_separator);
88 if (key_end_pos == std::string::npos)
89 {
90 // invalid member
91 valid_kv = false;
92 }
93 else
94 {
95 key = list_member.substr(0, key_end_pos);
96 value = list_member.substr(key_end_pos + 1);
97 }
98
99 index_ = end + 2;
100
101 return true;
102 }
103
104 // no more entries remaining
105 return false;
106 }
107
108 // Returns total number of tokens in header string
109 size_t NumTokens() const noexcept
110 {
111 size_t cnt = 0, begin = 0;
112 while (begin < str_.size())
113 {
114 ++cnt;
115 size_t end = str_.find(opts_.member_separator, begin);
116 if (end == std::string::npos)
117 {
118 break;
119 }
120
121 begin = end + 1;
122 }
123
124 return cnt;
125 }
126
127 // Resets the iterator
128 void reset() noexcept { index_ = 0; }
129
130private:
131 nostd::string_view str_;
132 KeyValueStringTokenizerOptions opts_;
133 size_t index_;
134};
135
136// Class to store fixed size array of key-value pairs of string type
137class KeyValueProperties
138{
139 // Class to store key-value pairs of string types
140public:
141 class Entry
142 {
143 public:
144 Entry() : key_(nullptr), value_(nullptr) {}
145
146 // Copy constructor
147 Entry(const Entry &copy)
148 {
149 key_ = CopyStringToPointer(copy.key_.get());
150 value_ = CopyStringToPointer(copy.value_.get());
151 }
152
153 // Copy assignment operator
154 Entry &operator=(Entry &other)
155 {
156 key_ = CopyStringToPointer(other.key_.get());
157 value_ = CopyStringToPointer(other.value_.get());
158 return *this;
159 }
160
161 // Move contructor and assignment operator
162 Entry(Entry &&other) = default;
163 Entry &operator=(Entry &&other) = default;
164
165 // Creates an Entry for a given key-value pair.
166 Entry(nostd::string_view key, nostd::string_view value)
167 {
168 key_ = CopyStringToPointer(key);
169 value_ = CopyStringToPointer(value);
170 }
171
172 // Gets the key associated with this entry.
173 nostd::string_view GetKey() const noexcept { return key_.get(); }
174
175 // Gets the value associated with this entry.
176 nostd::string_view GetValue() const noexcept { return value_.get(); }
177
178 // Sets the value for this entry. This overrides the previous value.
179 void SetValue(nostd::string_view value) noexcept { value_ = CopyStringToPointer(value); }
180
181 private:
182 // Store key and value as raw char pointers to avoid using std::string.
183 nostd::unique_ptr<const char[]> key_;
184 nostd::unique_ptr<const char[]> value_;
185
186 // Copies string into a buffer and returns a unique_ptr to the buffer.
187 // This is a workaround for the fact that memcpy doesn't accept a const destination.
188 nostd::unique_ptr<const char[]> CopyStringToPointer(nostd::string_view str)
189 {
190 char *temp = new char[str.size() + 1];
191 memcpy(temp, str.data(), str.size());
192 temp[str.size()] = '\0';
193 return nostd::unique_ptr<const char[]>(temp);
194 }
195 };
196
197 // Maintain the number of entries in entries_.
198 size_t num_entries_;
199
200 // Max size of allocated array
201 size_t max_num_entries_;
202
203 // Store entries in a C-style array to avoid using std::array or std::vector.
204 nostd::unique_ptr<Entry[]> entries_;
205
206public:
207 // Create Key-value list of given size
208 // @param size : Size of list.
209 KeyValueProperties(size_t size) noexcept
210 : num_entries_(0), max_num_entries_(size), entries_(new Entry[size])
211 {}
212
213 // Create Empty Key-Value list
214 KeyValueProperties() noexcept : num_entries_(0), max_num_entries_(0), entries_(nullptr) {}
215
216 template <class T, class = typename std::enable_if<detail::is_key_value_iterable<T>::value>::type>
217 KeyValueProperties(const T &keys_and_values) noexcept
218 : num_entries_(0),
219 max_num_entries_(keys_and_values.size()),
220 entries_(new Entry[max_num_entries_])
221 {
222 for (auto &e : keys_and_values)
223 {
224 Entry entry(e.first, e.second);
225 (entries_.get())[num_entries_++] = std::move(entry);
226 }
227 }
228
229 // Adds new kv pair into kv properties
230 void AddEntry(nostd::string_view key, nostd::string_view value) noexcept
231 {
232 if (num_entries_ < max_num_entries_)
233 {
234 Entry entry(key, value);
235 (entries_.get())[num_entries_++] = std::move(entry);
236 }
237 }
238
239 // Returns all kv pair entries
240 bool GetAllEntries(
241 nostd::function_ref<bool(nostd::string_view, nostd::string_view)> callback) const noexcept
242 {
243 for (size_t i = 0; i < num_entries_; i++)
244 {
245 auto &entry = (entries_.get())[i];
246 if (!callback(entry.GetKey(), entry.GetValue()))
247 {
248 return false;
249 }
250 }
251 return true;
252 }
253
254 // Return value for key if exists, return false otherwise
255 bool GetValue(nostd::string_view key, std::string &value) const noexcept
256 {
257 for (size_t i = 0; i < num_entries_; i++)
258 {
259 auto &entry = (entries_.get())[i];
260 if (entry.GetKey() == key)
261 {
262 const auto &entry_value = entry.GetValue();
263 value = std::string(entry_value.data(), entry_value.size());
264 return true;
265 }
266 }
267 return false;
268 }
269
270 size_t Size() const noexcept { return num_entries_; }
271};
272} // namespace common
273OPENTELEMETRY_END_NAMESPACE