4#include "Stroika/Frameworks/StroikaPreComp.h"
9#include "Stroika/Foundation/Characters/FloatConversion.h"
19using namespace Stroika::Frameworks;
20using namespace Stroika::Frameworks::UPnP;
26 optional<T> ParseInteger_ (
const String& text)
28 string s = text.
AsUTF8<
string> ();
29 if (s.starts_with (
'+')) {
33 auto [end, ec] = from_chars (s.data (), s.data () + s.size (), result);
34 if (ec != errc{} or end != s.data () + s.size () or s.empty ()) {
44 if constexpr (same_as<T, String>) {
47 else if constexpr (same_as<T, Character>) {
48 return text.
size () == 1 ? optional<T>{text[0]} : nullopt;
52 if constexpr (same_as<T, bool>) {
55 if (v ==
"1"sv or v ==
"true"sv or v ==
"yes"sv) {
58 if (v ==
"0"sv or v ==
"false"sv or v ==
"no"sv) {
63 else if constexpr (integral<T>) {
64 return ParseInteger_<T> (s);
66 else if constexpr (floating_point<T>) {
67 T v = FloatConversion::ToFloat<T> (s);
68 return std::isfinite (v) ? optional<T>{v} : nullopt;
70 else if constexpr (same_as<T, Time::Date>) {
73 else if constexpr (same_as<T, Time::DateTime>) {
74 return Time::DateTime::ParseQuietly (s, Time::DateTime::kISO8601Format);
76 else if constexpr (same_as<T, Time::TimeOfDay>) {
78 if (t == DataType::eTimeTZ) {
80 const string u = s.
AsUTF8<
string> ();
88 if constexpr (same_as<T, Memory::BLOB>) {
89 return t == DataType::eBinHex ?
Memory::BLOB::FromHex (s) : Cryptography::Encoding::Algorithm::Base64::Decode (s);
91 else if constexpr (same_as<T, IO::Network::URI>) {
95 static_assert (same_as<T, Common::GUID>);
114 return visit ([&]<
typename T> (
const T&) {
return ToText (v, DefaultDataType<T> ()); }, v);
120 [t]<
typename T> (
const T& x) ->
String {
121 Require (IsTypeOf<T> (t));
122 if constexpr (same_as<T, bool>) {
123 return x ?
"1"sv :
"0"sv;
125 else if constexpr (unsigned_integral<T>) {
126 return "{}"_f(
static_cast<uint64_t
> (x));
128 else if constexpr (signed_integral<T>) {
129 return "{}"_f(
static_cast<int64_t
> (x));
131 else if constexpr (floating_point<T>) {
132 Require (std::isfinite (x));
133 if (t == DataType::eFixed14_4) {
134 Require (std::abs (x) < 1e14);
145 else if constexpr (same_as<T, Character>) {
148 else if constexpr (same_as<T, String>) {
151 else if constexpr (same_as<T, Time::Date>) {
154 else if constexpr (same_as<T, Time::DateTime>) {
155 if (t == DataType::eDateTime) {
158 if (optional<Time::TimeOfDay> tod = x.GetTimeOfDay ()) {
163 return x.Format (Time::DateTime::kISO8601Format);
165 else if constexpr (same_as<T, Time::TimeOfDay>) {
168 else if constexpr (same_as<T, Memory::BLOB>) {
169 if (t == DataType::eBinHex) {
172 using namespace Cryptography::Encoding::Algorithm;
173 return String{Base64::Encode (x, Base64::Options{.fLineBreak = Base64::LineBreak::eNone_LB})};
176 static_assert (same_as<T, IO::Network::URI> or same_as<T, Common::GUID>);
177 return x.template As<String> ();
191 auto as = [&]<IValue T> () -> optional<Value> {
192 if (optional<T> v = Read_<T> (text, t)) {
193 return Value{in_place_type<T>, *v};
199 return as.template operator()<uint8_t> ();
201 return as.template operator()<uint16_t> ();
203 return as.template operator()<uint32_t> ();
205 return as.template operator()<uint64_t> ();
207 return as.template operator()<int8_t> ();
209 return as.template operator()<int16_t> ();
212 return as.template operator()<int32_t> ();
214 return as.template operator()<int64_t> ();
216 return as.template operator()<
float> ();
218 case DataType::eNumber:
219 case DataType::eFixed14_4:
220 case DataType::eFloat:
221 return as.template operator()<
double> ();
222 case DataType::eChar:
223 return as.template operator()<
Character> ();
224 case DataType::eString:
225 return as.template operator()<
String> ();
226 case DataType::eDate:
228 case DataType::eDateTime:
229 case DataType::eDateTimeTZ:
230 return as.template operator()<Time::DateTime> ();
231 case DataType::eTime:
232 case DataType::eTimeTZ:
234 case DataType::eBoolean:
235 return as.template operator()<
bool> ();
236 case DataType::eBinBase64:
237 case DataType::eBinHex:
241 case DataType::eUUID:
#define AssertNotReached()
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual T AsUTF8() const
nonvirtual size_t size() const noexcept
nonvirtual bool EndsWith(const Character &c, CompareOptions co=eWithCase) const
nonvirtual String ToLowerCase() const
nonvirtual String ReplaceAll(const RegularExpression ®Ex, const String &with) const
nonvirtual String SubString(SZ from) const
nonvirtual String Trim(bool(*shouldBeTrimmed)(Character)=Character::IsWhitespace) const
nonvirtual String substr(size_t from, size_t count=npos) const
static URI Parse(const String &rawURL)
static BLOB FromHex(const char *b)
Convert string of hex bytes to BLOB.
static constexpr string_view kISO8601Format
Y-M-D format - locale independent, and ISO-8601 date format standard.
static optional< Date > ParseQuietly(const String &rep, const String &formatPattern)
like Parse(), but returns nullopt on parse error, not throwing exception. if locale is missing,...
static constexpr string_view kISO8601Format
static optional< TimeOfDay > ParseQuietly(const String &rep, const String &formatPattern)
like Parse(), but returns nullopt on parse error, not throwing exception. if locale is missing,...
variant< bool, uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t, float, double, Foundation::Characters::Character, String, Foundation::Time::Date, Foundation::Time::DateTime, Foundation::Time::TimeOfDay, Foundation::Memory::BLOB, Foundation::IO::Network::URI, Foundation::Common::GUID > Value
A value of any of UPnP's data types, as its C++ type (the table above) - for code that learns a value...
DataType
UPnP's data types - each named, as a service's description names it (Common::DefaultNames): ui2,...
optional< T > FromText(const String &text)
text read as UPnP reads it: as t, if given, else as T's default data type (the table above) - nullopt...
String ToText(const T &v)
v, as UPnP writes it: as t, if given, else as its C++ type's default data type (the table above)