Audacity 3.2.0
XMLAttributeValueView.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 XMLAttributeValueView.cpp
6
7 Dmitry Vedenko
8
9**********************************************************************/
10
12#include "FromChars.h"
13
14#include <numeric>
15
17 : mInteger(value)
18 , mType(Type::UnsignedInteger)
19{
20}
21
23 : mInteger(value)
24 , mType(Type::SignedInteger)
25{
26}
27
29 : mInteger(value)
30 , mType(Type::UnsignedInteger)
31{
32}
33
35 : mInteger(value)
36 , mType(Type::SignedInteger)
37{
38}
39
41 : mInteger(value)
42 , mType(Type::UnsignedInteger)
43{
44}
45
47 : mInteger(value)
48 , mType(Type::SignedInteger)
49{
50}
51
53 : mInteger(value)
54 , mType(Type::UnsignedInteger)
55{
56}
57
59 : mInteger(value)
60 , mType(Type::SignedInteger)
61{
62}
63
64XMLAttributeValueView::XMLAttributeValueView(unsigned long long value) noexcept
65 : mInteger(value)
66 , mType(Type::UnsignedInteger)
67{
68}
69
71 : mFloat(value)
72 , mType(Type::Float)
73{
74}
75
77 : mDouble(value)
78 , mType(Type::Double)
79{
80}
81
83 const std::string_view& value) noexcept
84 : mType(Type::StringView)
85{
86 mStringView.Data = value.data();
87 mStringView.Length = value.length();
88}
89
91{
92 return mType;
93}
94
95bool XMLAttributeValueView::IsNull() const noexcept
96{
97 return mType == Type::Null;
98}
99
101{
102 return mType == Type::SignedInteger;
103}
104
106{
108}
109
111{
112 return mType == Type::Float;
113}
114
116{
117 return mType == Type::Double;
118}
119
121{
122 return mType == Type::StringView;
123}
124
125bool XMLAttributeValueView::TryGet(bool& value) const noexcept
126{
127 return TryGetInteger(value);
128}
129
130bool XMLAttributeValueView::TryGet(short& value) const noexcept
131{
132 return TryGetInteger(value);
133}
134
135bool XMLAttributeValueView::TryGet(unsigned short& value) const noexcept
136{
137 return TryGetInteger(value);
138}
139
140bool XMLAttributeValueView::TryGet(int& value) const noexcept
141{
142 return TryGetInteger(value);
143}
144
145bool XMLAttributeValueView::TryGet(unsigned int& value) const noexcept
146{
147 return TryGetInteger(value);
148}
149
150bool XMLAttributeValueView::TryGet(long& value) const noexcept
151{
152 return TryGetInteger(value);
153}
154
155bool XMLAttributeValueView::TryGet(unsigned long& value) const noexcept
156{
157 return TryGetInteger(value);
158}
159
160bool XMLAttributeValueView::TryGet(long long& value) const noexcept
161{
162 return TryGetInteger(value);
163}
164
165bool XMLAttributeValueView::TryGet(unsigned long long& value) const noexcept
166{
167 return TryGetInteger(value);
168}
169
170bool XMLAttributeValueView::TryGet(float& value) const noexcept
171{
172 if (mType == Type::Float)
173 {
174 value = mFloat;
175 return true;
176 }
177 else if (mType == Type::SignedInteger || mType == Type::UnsignedInteger)
178 {
179 value = mInteger;
180 return true;
181 }
182 else if (mType == Type::StringView)
183 {
184 const char* end = mStringView.Data + mStringView.Length;
185
186 float tempValue = {};
187
188 const auto result = FromChars(mStringView.Data, end, tempValue);
189
190 if (result.ec == std::errc() && result.ptr == end)
191 {
192 value = tempValue;
193 return true;
194 }
195 }
196
197 return false;
198}
199
200bool XMLAttributeValueView::TryGet(double& value) const noexcept
201{
202 if (mType == Type::Float)
203 {
204 value = mFloat;
205 return true;
206 }
207 else if (mType == Type::Double)
208 {
209 value = mDouble;
210 return true;
211 }
212 else if (mType == Type::SignedInteger || mType == Type::UnsignedInteger)
213 {
214 value = mInteger;
215 return true;
216 }
217 else if (mType == Type::StringView)
218 {
219 const char* end = mStringView.Data + mStringView.Length;
220
221 double tempValue = {};
222
223 const auto result = FromChars(mStringView.Data, end, tempValue);
224
225 if (result.ec == std::errc() && result.ptr == end)
226 {
227 value = tempValue;
228 return true;
229 }
230 }
231
232 return false;
233}
234
235bool XMLAttributeValueView::TryGet(std::string_view& value) const noexcept
236{
237 if (mType != Type::StringView)
238 return false;
239
240 value = std::string_view(mStringView.Data, mStringView.Length);
241
242 return true;
243}
244
246{
247 switch (mType)
248 {
250 return {};
252 return std::to_string(mInteger);
254 return std::to_string(static_cast<uint64_t>(mInteger));
256 return std::to_string(mFloat);
258 return std::to_string(mDouble);
260 return std::string(mStringView.Data, mStringView.Length);
261 }
262
263 return {};
264}
265
267{
268 switch (mType)
269 {
271 return {};
273 return wxString() << mInteger;
275 return wxString() << static_cast<uint64_t>(mInteger);
277 return wxString() << mFloat;
279 return wxString() << mDouble;
281 return wxString::FromUTF8(mStringView.Data, mStringView.Length);
282 }
283
284 return {};
285}
286
287template <typename ResultType>
288bool CheckInteger(ResultType& output, int64_t value) noexcept
289{
290 constexpr int64_t minValue = std::numeric_limits<ResultType>::min();
291 constexpr int64_t maxValue = std::numeric_limits<ResultType>::max();
292
293 if (minValue <= value && value <= maxValue)
294 {
295 output = static_cast<ResultType>(value);
296 return true;
297 }
298
299 return false;
300}
301
302template <typename ResultType>
303bool CheckInteger(ResultType& output, uint64_t value) noexcept
304{
305 constexpr uint64_t maxValue = std::numeric_limits<ResultType>::max();
306 const uint64_t unsignedValue = static_cast<uint64_t>(value);
307
308 if (unsignedValue <= maxValue)
309 {
310 output = static_cast<ResultType>(unsignedValue);
311 return true;
312 }
313
314 return false;
315}
316
317template <typename ResultType>
318bool XMLAttributeValueView::TryGetInteger(ResultType& value) const noexcept
319{
320 static_assert(std::is_integral_v<ResultType>);
321
322 if (mType == Type::SignedInteger)
323 {
324 return CheckInteger(value, mInteger);
325 }
326 else if (mType == Type::UnsignedInteger)
327 {
328 return CheckInteger(value, static_cast<uint64_t>(mInteger));
329 }
330 else if (mType == Type::StringView)
331 {
332 const char* end = mStringView.Data + mStringView.Length;
333
334 ResultType tempValue = {};
335
336 const auto result = FromChars(mStringView.Data, end, tempValue);
337
338 if (result.ec == std::errc() && result.ptr == end)
339 {
340 value = tempValue;
341 return true;
342 }
343 }
344
345 return false;
346}
int min(int a, int b)
FromCharsResult FromChars(const char *buffer, const char *last, float &value) noexcept
Parse a string into a single precision floating point value, always uses the dot as decimal.
Definition: FromChars.cpp:153
Declare functions to convert numeric types to string representation.
bool CheckInteger(ResultType &output, int64_t value) noexcept
bool IsUnsignedInteger() const noexcept
Check if view has the UnsignedInteger type.
std::string ToString() const
Convert the view value to an UTF8 string.
bool IsNull() const noexcept
Check if view is Null.
wxString ToWString() const
Convert the view value to wxString.
bool IsSignedInteger() const noexcept
Check if view has the SignedInteger type.
struct XMLAttributeValueView::@138::@140 mStringView
XMLAttributeValueView()=default
Construct an uninitialized view of type Null.
Type
Type of the value represented by the XMLAttributeValueView.
@ Float
The value is a single precision floating point value.
@ SignedInteger
The value is a signed integer.
@ UnsignedInteger
The value is an unsigned integer.
@ Null
The value is not initialized.
@ StringView
The value is a string_view.
@ Double
The value is a double precision floating point value.
bool IsStringView() const noexcept
Check if view has the StringView type.
bool TryGetInteger(ResultType &value) const noexcept
bool IsFloat() const noexcept
Check if view has the Float type.
bool IsDouble() const noexcept
Check if view has the Double type.
Type GetType() const noexcept
Get the view type.
bool TryGet(bool &value) const noexcept
Try to get a boolean value from the view.
const char * end(const char *str) noexcept
Definition: StringUtils.h:106