Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Advertisement.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
11#include "Stroika/Foundation/Streams/MemoryStream.h"
12#include "Stroika/Foundation/Streams/TextToBinary.h"
13
15
16#include "Advertisement.h"
17
18using std::byte;
19
20using namespace Stroika::Foundation;
22using namespace Stroika::Foundation::Streams;
24
25using namespace Stroika::Frameworks;
26using namespace Stroika::Frameworks::UPnP;
27using namespace Stroika::Frameworks::UPnP::SSDP;
28
29/*
30 ********************************************************************************
31 ****************************** SSDP::Advertisement *****************************
32 ********************************************************************************
33 */
34String Advertisement::ToString () const
35{
37 sb << "{"sv;
38 if (fAlive) {
39 sb << "Alive : "sv << fAlive;
40 }
41 sb << ", USN : "sv << fUSN;
42 sb << ", Location : "sv << fLocation;
43 sb << ", Server : "sv << fServer;
44 sb << ", Target : "sv << fTarget;
45 sb << ", Raw-Headers : "sv << fRawHeaders;
46 sb << "}"sv;
47 return sb;
48}
49
50ObjectVariantMapper Advertisement::kMapperGetter_ ()
51{
53 mapper.AddCommonType<Set<String>> ();
54 mapper.AddCommonType<optional<Set<String>>> ();
55 mapper.AddClass<Advertisement> ({
56 {"Alive"sv, &Advertisement::fAlive},
57 {"USN"sv, &Advertisement::fUSN},
58 {"Server"sv, &Advertisement::fServer},
59 {"Target"sv, &Advertisement::fTarget},
60 {"RawHeaders"sv, &Advertisement::fRawHeaders},
61 });
62 return mapper;
63};
64
65/*
66 ********************************************************************************
67 ******************************* SSDP::Serialize ********************************
68 ********************************************************************************
69 */
70Memory::BLOB SSDP::Serialize (const String& headLine, SearchOrNotify searchOrNotify, const Advertisement& ad)
71{
72 using namespace Characters::Literals;
73 Require (not headLine.Contains ("\n"));
74 Require (not headLine.Contains ("\r"));
75 Require (headLine.StartsWith ("NOTIFY") or (headLine == "HTTP/1.1 200 OK"));
76 Streams::MemoryStream::Ptr<byte> out = Streams::MemoryStream::New<byte> ();
77 Streams::TextToBinary::Writer::Ptr textOut = Streams::TextToBinary::Writer::New (out, UnicodeExternalEncodings::eUTF8, ByteOrderMark::eDontInclude);
78
79 //// SUPER ROUGH FIRST DRAFT
80 textOut.Write ("{}\r\n"_f(headLine));
81 textOut.Write ("Host: {}:{}\r\n"_f(SSDP::V4::kSocketAddress.GetInternetAddress (), SSDP::V4::kSocketAddress.GetPort ()));
82 textOut.Write ("Cache-Control: max-age=60\r\n"sv); // @todo fix
83 textOut.Write ("Location: {}\r\n"_f(ad.fLocation));
84 if (ad.fAlive.has_value ()) {
85 if (*ad.fAlive) {
86 textOut.Write ("NTS: ssdp:alive\r\n"sv);
87 }
88 else {
89 textOut.Write ("NTS: ssdp:byebye\r\n"sv);
90 }
91 }
92 if (not ad.fServer.empty ()) {
93 textOut.Write ("Server: {}\r\n"_f(ad.fServer));
94 }
95 if (searchOrNotify == SearchOrNotify::SearchResponse) {
96 textOut.Write ("ST: {}\r\n"_f(ad.fTarget));
97 }
98 else {
99 textOut.Write ("NT: {}\r\n"_f(ad.fTarget));
100 }
101 textOut.Write ("USN: {}\r\n"_f(ad.fUSN));
102
103 // Terminate list of headers
104 textOut.Write ("\r\n"sv);
105
106 // need flush API on
107
108 return out.As<Memory::BLOB> ();
109}
110
111/*
112 ********************************************************************************
113 **************************** SSDP::DeSerialize *********************************
114 ********************************************************************************
115 */
116void SSDP::DeSerialize (const Memory::BLOB& b, String* headLine, Advertisement* advertisement)
117{
118 RequireNotNull (headLine);
119 RequireNotNull (advertisement);
120 *advertisement = Advertisement{};
121
122#if qCompilerAndStdLib_span_requires_explicit_type_for_BLOBCVT_Buggy
123 BinaryToText::Reader::Ptr in = BinaryToText::Reader::New (ExternallyOwnedSpanInputStream::New<byte> (span<const byte>{b}));
124#else
125 BinaryToText::Reader::Ptr in = BinaryToText::Reader::New (ExternallyOwnedSpanInputStream::New<byte> (span{b}));
126#endif
127
128 *headLine = in.ReadLine ().Trim ();
129 while (true) {
130 String line = in.ReadLine ().Trim ();
131 if (line.empty ()) {
132 break;
133 }
134
135 // Need to simplify this code (stroika string util)
136 String label;
137 String value;
138 if (optional<size_t> n = line.Find (':')) {
139 label = line.SubString (0, *n);
140 value = line.SubString (*n + 1).Trim ();
141 }
142 if (not label.empty ()) {
143 advertisement->fRawHeaders.Add (label, value);
144 }
145 constexpr auto kLabelComparer_ = String::ThreeWayComparer{Characters::eCaseInsensitive};
146 if (kLabelComparer_ (label, "Location"sv) == 0) {
147 advertisement->fLocation = IO::Network::URI{value};
148 }
149 else if (kLabelComparer_ (label, "NT"sv) == 0) {
150 advertisement->fTarget = value;
151 }
152 else if (kLabelComparer_ (label, "USN"sv) == 0) {
153 advertisement->fUSN = value;
154 }
155 else if (kLabelComparer_ (label, "Server"sv) == 0) {
156 advertisement->fServer = value;
157 }
158 else if (kLabelComparer_ (label, "NTS"sv) == 0) {
159 constexpr auto kValueComparer_ = String::ThreeWayComparer{Characters::eCaseInsensitive};
160 if (kValueComparer_ (value, "ssdp:alive"sv) == 0) {
161 advertisement->fAlive = true;
162 }
163 else if (kValueComparer_ (value, "ssdp:byebye"sv) == 0) {
164 advertisement->fAlive = false;
165 }
166 }
167 }
168}
#define RequireNotNull(p)
Definition Assertions.h:347
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,...
Definition String.h:201
nonvirtual bool Contains(Character c, CompareOptions co=eWithCase) const
Definition String.inl:693
nonvirtual String SubString(SZ from) const
nonvirtual String Trim(bool(*shouldBeTrimmed)(Character)=Character::IsWhitespace) const
Definition String.cpp:1592
nonvirtual bool StartsWith(const Character &c, CompareOptions co=eWithCase) const
Definition String.cpp:1059
nonvirtual optional< size_t > Find(Character c, CompareOptions co=eWithCase) const
Definition String.inl:681
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
Definition Set.h:105
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)
InputStream<>::Ptr is Smart pointer (with abstract Rep) class defining the interface to reading from ...
OutputStream<>::Ptr is Smart pointer to a stream-based sink of data.
nonvirtual void Write(span< ELEMENT_TYPE2, EXTENT_2 > elts) const
Ptr New(const InputStream::Ptr< byte > &src, optional< AutomaticCodeCvtFlags > codeCvtFlags={}, optional< SeekableFlag > seekable={}, ReadAhead readAhead=eReadAheadAllowed)
Create an InputStream::Ptr<Character> from the arguments (usually binary source) - which can be used ...