4#include "Stroika/Frameworks/StroikaPreComp.h"
12#include "Stroika/Foundation/Execution/Throw.h"
16#include "DeviceDescription.h"
27using Memory::MakeSharedPtr;
29using namespace Stroika::Frameworks;
30using namespace Stroika::Frameworks::UPnP;
34 const IO::Network::URI kDeviceNamespace_{
"urn:schemas-upnp-org:device-1-0"sv};
64 static const Binding kBinding_ = [] () {
65 constexpr auto kSkip = Binding::UndeclaredMembers::eSkip;
66 auto text = [] () {
return Binding{.
fType = VariantValue::eString}; };
67 auto size = [] () {
return Binding{.fType = VariantValue::eUnsignedInteger}; };
68 auto list = [] (
const Binding& item) {
69 return Binding{.fType = VariantValue::eArray,
70 .fUndeclaredMembers = Binding::UndeclaredMembers::eSkip,
71 .fItems = MakeSharedPtr<Binding> (item)};
73 Binding icon{.fName =
"icon"sv,
74 .fType = VariantValue::eMap,
75 .fMembers = {{
"mimetype"sv, text ()}, {
"width"sv, size ()}, {
"height"sv, size ()}, {
"depth"sv, size ()}, {
"url"sv, text ()}},
76 .fUndeclaredMembers = kSkip};
79 .fType = VariantValue::eMap,
80 .fMembers = {{
"serviceType"sv, text ()}, {
"serviceId"sv, text ()}, {
"SCPDURL"sv, text ()}, {
"controlURL"sv, text ()}, {
"eventSubURL"sv, text ()}},
81 .fUndeclaredMembers = kSkip};
83 Binding device{.fType = VariantValue::eMap,
84 .fMembers = {{
"deviceType"sv, text ()},
85 {
"friendlyName"sv, text ()},
86 {
"manufacturer"sv, text ()},
87 {
"manufacturerURL"sv, text ()},
88 {
"modelDescription"sv, text ()},
89 {
"modelName"sv, text ()},
90 {
"modelNumber"sv, text ()},
91 {
"modelURL"sv, text ()},
92 {
"serialNumber"sv, text ()},
95 {
"iconList"sv, list (icon)},
96 {
"serviceList"sv, list (service)},
97 {
"presentationURL"sv, text ()}},
98 .fUndeclaredMembers = kSkip};
99 Binding specVersion{.fType = VariantValue::eMap, .fMembers = {{
"major"sv, text ()}, {
"minor"sv, text ()}}, .fUndeclaredMembers = kSkip};
101 .fType = VariantValue::eMap,
102 .fMembers = {{
"specVersion"sv, specVersion}, {
"URLBase"sv, text ()}, {
"device"sv, device}},
103 .fUndeclaredMembers = kSkip};
104 Ensure (root.IsComplete ());
120 sb <<
"mimeType: "sv << fMimeType;
121 sb <<
", horizontalPixels: "sv << fHorizontalPixels;
122 sb <<
", nerticalPixels: "sv << fVerticalPixels;
123 sb <<
", colorDepth : "sv << fColorDepth;
124 sb <<
", URL: "sv << fURL;
138 sb <<
"Service-Type: "sv << fServiceType;
139 sb <<
", Service-ID: "sv << fServiceID;
140 sb <<
", SCPD-URL: "sv << fSCPDURL;
141 sb <<
", Control-URL: "sv << fControlURL;
142 sb <<
", Event-Sub-URL: "sv << fEventSubURL;
156 if (fPresentationURL) {
157 sb <<
"Presentation-URL: "sv << fPresentationURL;
160 sb <<
", URL-Base: "sv << *
fURLBase;
162 sb <<
", Device-Type: "sv << fDeviceType;
163 sb <<
", Manufacture-Name: "sv << fManufactureName;
164 sb <<
", Friendly-Name: "sv << fFriendlyName;
165 if (fManufacturingURL) {
166 sb <<
", Manufacturing-URL: "sv << fManufacturingURL;
168 if (fModelDescription) {
169 sb <<
", Model-Description: "sv << fModelDescription;
171 sb <<
", Model-Name: "sv << fModelName;
173 sb <<
", Model-Number: "sv << fModelNumber;
176 sb <<
", Model-URL: "sv << *fModelURL;
179 sb <<
", Serial-Number: "sv << fSerialNumber;
181 sb <<
", UDN: "sv <<
fUDN;
183 sb <<
", UPC: "sv << fUPC;
186 sb <<
", Icons: "sv << fIcons;
189 sb <<
", Services: "sv << fServices;
197 const URI base =
fURLBase.value_or (descriptionURL);
198 auto resolve = [&] (
const URI& u) {
return u ? base.
Combine (u) : u; };
201 for (optional<URI>* u : {&result.fPresentationURL, &result.fManufacturingURL, &result.fModelURL}) {
208 i.fURL = resolve (i.fURL);
214 s.fSCPDURL = resolve (s.fSCPDURL);
215 s.fControlURL = resolve (s.fControlURL);
216 s.fEventSubURL = resolve (s.fEventSubURL);
228 {
"mimetype"sv, &Icon::fMimeType},
229 {
"width"sv, &Icon::fHorizontalPixels},
230 {
"height"sv, &Icon::fVerticalPixels},
231 {
"depth"sv, &Icon::fColorDepth},
232 {
"url"sv, &Icon::fURL},
238 {
"serviceType"sv, &Service::fServiceType},
239 {
"serviceId"sv, &Service::fServiceID},
240 {
"SCPDURL"sv, &Service::fSCPDURL},
241 {
"controlURL"sv, &Service::fControlURL},
242 {
"eventSubURL"sv, &Service::fEventSubURL},
252 {
"presentationURL"sv, &DeviceDescription::fPresentationURL},
253 {
"deviceType"sv, &DeviceDescription::fDeviceType},
254 {
"manufacturer"sv, &DeviceDescription::fManufactureName},
255 {
"friendlyName"sv, &DeviceDescription::fFriendlyName},
256 {
"manufacturerURL"sv, &DeviceDescription::fManufacturingURL},
257 {
"modelDescription"sv, &DeviceDescription::fModelDescription},
258 {
"modelName"sv, &DeviceDescription::fModelName},
259 {
"modelNumber"sv, &DeviceDescription::fModelNumber},
260 {
"modelURL"sv, &DeviceDescription::fModelURL},
261 {
"serialNumber"sv, &DeviceDescription::fSerialNumber},
263 {
"UPC"sv, &DeviceDescription::fUPC},
264 {
"iconList"sv, &DeviceDescription::fIcons},
265 {
"serviceList"sv, &DeviceDescription::fServices},
278 VVMap_ device = Mapper_ ().FromObject (dd).
As<VVMap_> ();
281 if (optional<VariantValue> urlBase = device.Lookup (
"URLBase"sv)) {
282 root.Add (
"URLBase"sv, *urlBase);
283 device.Remove (
"URLBase"sv);
289#if qStroika_Foundation_DataExchange_XML_SupportParsing and qStroika_Foundation_DataExchange_XML_SupportSchema and qStroika_Foundation_DataExchange_XML_SupportDOM
290 if (options.fValidateWrite) {
292 options.fXMLOptions);
305#if USE_NOISY_TRACE_IN_THIS_MODULE_
312 VVMap_ device = root.LookupValue (
"device"sv).As<VVMap_> ();
315 if (optional<VariantValue> urlBase = root.Lookup (
"URLBase"sv)) {
322 DbgTrace (
"Ignoring <URLBase>{}</URLBase>, which is not a URL: {}"_f, u, current_exception ());
327#if USE_NOISY_TRACE_IN_THIS_MODULE_
328 DbgTrace (
"deviceDescription: {}"_f, deviceDescription);
330 return deviceDescription;
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 String Trim(bool(*shouldBeTrimmed)(Character)=Character::IsWhitespace) const
A Collection<T> is a container to manage an un-ordered collection of items, without equality defined ...
A Mapping uniquely associates two elements: a key and a value (use Assocation to allow multiple value...
ObjectVariantMapper can be used to map C++ types to and from variant-union types, which can be transp...
nonvirtual void AddClass(const Traversal::Iterable< StructFieldInfo > &fieldDescriptions, const ClassMapperOptions< CLASS > &mapperOptions={})
nonvirtual void AddCommonType(ARGS &&... args)
nonvirtual void Add(const TypeMappingDetails &s)
Read XML as a VariantValue - the inverse of Variant::XML::Writer, whose documentation has the shape.
Write a VariantValue as XML - an object's member is an element, an array is repeated elements.
Simple variant-value (case variant union) object, with (variant) basic types analogous to a value in ...
nonvirtual RETURNTYPE As() const
static URI Parse(const String &rawURL)
nonvirtual URI Combine(const URI &overridingURI) const
Combine overridingURI possibly relative url with this base url, to produce a new URI.
Ptr New(const InputStream::Ptr< byte > &src, optional< SeekableFlag > seekable={}, ReadAhead readAhead=eReadAheadAllowed)
Create an InputStream::Ptr<Character> from the arguments (usually binary source) - which can be used ...
How a VariantValue is to be written as XML, and read back, where the default shape (.
optional< VariantValue::Type > fType
An element's or attribute's name (local-name, not including a prefix), plus the namespace that name i...
nonvirtual String ToString() const
What Serialize and DeSerialize of a device description are told - defaulted, so a caller says only wh...
Foundation::DataExchange::XML::Options fXMLOptions
The XML provider that reads, and that checks what is written - by default, Stroika's default provider...
Foundation::DataExchange::XML::Schema::Ptr fValidateReadAgainst
Check a description being read against this schema - DeviceDescriptionSchema - throwing where it does...
nonvirtual String ToString() const
nonvirtual String ToString() const
nonvirtual DeviceDescription Resolve(const URI &descriptionURL) const
This description with every URL absolute - each relative one resolved against fURLBase,...
static const Foundation::Execution::LazyInitialized< Foundation::DataExchange::ObjectVariantMapper > kMapper