Envelope.h
Go to the documentation of this file.
1 /****
2  * Envelope.h
3  *
4  * Copyright 2019 mikee47 <mike@sillyhouse.net>
5  *
6  * This file is part of the Sming UPnP Library
7  *
8  * This library is free software: you can redistribute it and/or modify it under the terms of the
9  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with this library.
16  * If not, see <https://www.gnu.org/licenses/>.
17  *
18  ****/
19 
20 #pragma once
21 
22 #include <RapidXML.h>
23 #include "Error.h"
24 #include "ErrorCode.h"
25 #include "Base64.h"
26 
27 namespace UPnP
28 {
30 class Service;
31 
35 class Envelope
36 {
37 public:
38  enum class ContentType {
39  none,
40  fault,
41  request,
42  response,
43  };
44 
45  class Fault
46  {
47  public:
48  Fault(Envelope& envelope) : envelope(envelope)
49  {
50  }
51 
52  explicit operator bool() const
53  {
54  return envelope.isFault();
55  }
56 
57  String faultCode() const;
61 
62  size_t printTo(Print& p) const;
63 
64  private:
65  Envelope& envelope;
66  XML::Node* detail() const;
67  XML::Node* error() const;
68  };
69 
71  {
72  }
73 
77  void clear();
78 
79  bool isEmpty() const
80  {
81  return type == ContentType::none;
82  }
83 
84  bool isFault() const
85  {
86  return type == ContentType::fault;
87  }
88 
95  Error load(String&& content);
96 
97  Error load(const FlashString& content);
103  String serialize(bool pretty)
104  {
105  prepareResponse();
106  return XML::serialize(doc, pretty);
107  }
108 
112  size_t serialize(Print& p, bool pretty)
113  {
114  prepareResponse();
115  return XML::serialize(doc, p, pretty);
116  }
117 
122  {
123  return type;
124  }
125 
130  {
131  return name;
132  }
133 
138 
143 
148  {
149  if(type == ContentType::request) {
150  type = ContentType::response;
151  responsePrepared = false;
152  }
153  }
154 
160  {
161  if(type == Envelope::ContentType::response && !responsePrepared) {
163  }
164  }
165 
170 
176  {
177  return Fault(*this);
178  }
179 
180  const Fault fault() const
181  {
182  return Fault(*const_cast<Envelope*>(this));
183  }
184 
191  const char* getArgValue(const String& name) const
192  {
193  auto node = XML::getNode(content, name, "");
194  return node ? node->value() : nullptr;
195  }
196 
197  String getArg(const String& name) const
198  {
199  return XML::getValue(content, name, "");
200  }
201 
202  bool getArg(const String& name, char& value, char defaultValue = '?')
203  {
204  auto s = getArgValue(name);
205  if(s == nullptr) {
206  value = defaultValue;
207  return false;
208  }
209 
210  value = *s;
211  return true;
212  }
213 
214  bool getArg(const String& name, String& value)
215  {
216  value = getArg(name);
217  return bool(value);
218  }
219 
220  template <typename T>
221  typename std::enable_if<std::is_unsigned<T>::value && !std::is_floating_point<T>::value, bool>::type
222  getArg(const String& name, T& value, T defaultValue = T{})
223  {
224  uint32_t n;
225  if(!getArg(name, n, defaultValue)) {
226  value = defaultValue;
227  return false;
228  }
229 
230  value = n;
231  return true;
232  }
233 
234  template <typename T>
235  typename std::enable_if<std::is_signed<T>::value && !std::is_floating_point<T>::value, bool>::type
236  getArg(const String& name, T& value, T defaultValue = T{})
237  {
238  int32_t n;
239  if(!getArg(name, n, defaultValue)) {
240  value = defaultValue;
241  return false;
242  }
243 
244  value = n;
245  return true;
246  }
247 
248  bool getArg(const String& name, bool& value, bool defaultValue = false);
249  bool getArg(const String& name, uint32_t& value, uint32_t defaultValue = 0);
250  bool getArg(const String& name, int32_t& value, int32_t defaultValue = 0);
251  bool getArg(const String& name, float& value, float defaultValue = 0.0);
252  bool getArg(const String& name, double& value, double defaultValue = 0.0);
253 
254  bool getArg(const String& name, Base64& value)
255  {
256  value = getArgValue(name);
257  return bool(value);
258  }
259 
266  bool addArg(const String& name, const String& value)
267  {
268  prepareResponse();
269  assert(type == ContentType::request || type == ContentType::response);
270  XML::appendNode(content, name, value);
271  return true;
272  }
273 
274  bool addArg(const String& name, const char* value)
275  {
276  return addArg(name, String(value));
277  }
278 
279  bool addArg(const String& name, bool value)
280  {
281  return addArg(name, value ? "1" : "0");
282  }
283 
284  bool addArg(const String& name, const Base64& value)
285  {
286  return addArg(name, value.encode());
287  }
288 
289  template <typename T> bool addArg(const String& name, T value)
290  {
291  return addArg(name, String(value));
292  }
293 
297 
298  const Service& service;
299 
300 private:
301  Error parseBody();
302  Error verifyObjectType(const String& objectType) const;
303  XML::Node* initialise(ContentType contentType);
304 
305  XML::Document doc;
306  String buffer;
307  String name;
308  XML::Node* content{nullptr};
309  ContentType type{};
310  Error lastError{};
311  bool responsePrepared{false};
312 };
313 
314 } // namespace UPnP
describes a counted string stored in flash memory
Definition: String.hpp:174
Provides formatted output to stream.
Definition: Print.h:37
The String class.
Definition: WString.h:137
Definition: Base64.h:28
String encode() const
Definition: Base64.h:58
Definition: Envelope.h:46
size_t printTo(Print &p) const
String faultCode() const
ErrorCode errorCode() const
Fault(Envelope &envelope)
Definition: Envelope.h:48
String faultString() const
String errorDescription() const
Class to manage a SOAP envelope for service request/response.
Definition: Envelope.h:36
Envelope(const Service &service)
Definition: Envelope.h:70
bool getArg(const String &name, float &value, float defaultValue=0.0)
String getArg(const String &name) const
Definition: Envelope.h:197
bool getArg(const String &name, bool &value, bool defaultValue=false)
std::enable_if< std::is_unsigned< T >::value &&!std::is_floating_point< T >::value, bool >::type getArg(const String &name, T &value, T defaultValue=T{})
Definition: Envelope.h:222
bool getArg(const String &name, String &value)
Definition: Envelope.h:214
Error load(String &&content)
Load a SOAP document.
const Fault fault() const
Definition: Envelope.h:180
bool addArg(const String &name, bool value)
Definition: Envelope.h:279
bool getArg(const String &name, int32_t &value, int32_t defaultValue=0)
Fault fault()
Definition: Envelope.h:175
bool getArg(const String &name, Base64 &value)
Definition: Envelope.h:254
Error load(const FlashString &content)
bool addArg(const String &name, const String &value)
Definition: Envelope.h:266
ContentType contentType() const
Get the current envelope content type.
Definition: Envelope.h:121
void convertToResponse()
Set a flag that this should be converted to Response on next setArg() call.
Definition: Envelope.h:147
bool getArg(const String &name, uint32_t &value, uint32_t defaultValue=0)
std::enable_if< std::is_signed< T >::value &&!std::is_floating_point< T >::value, bool >::type getArg(const String &name, T &value, T defaultValue=T{})
Definition: Envelope.h:236
const Service & service
Definition: Envelope.h:298
void prepareResponse()
If Response is required but hasn't been prepared yet, do it now. This wipes out the incoming request.
Definition: Envelope.h:159
const char * getArgValue(const String &name) const
Definition: Envelope.h:191
size_t serialize(Print &p, bool pretty)
Serialize XML content to a stream.
Definition: Envelope.h:112
bool isFault() const
Definition: Envelope.h:84
bool addArg(const String &name, const char *value)
Definition: Envelope.h:274
bool addArg(const String &name, T value)
Definition: Envelope.h:289
bool isEmpty() const
Definition: Envelope.h:79
Envelope & createRequest(const String &actionName)
Initialise the envelope as a request.
String serialize(bool pretty)
Obtain content as XML string.
Definition: Envelope.h:103
void clear()
Wipe the envelope contents.
bool addArg(const String &name, const Base64 &value)
Definition: Envelope.h:284
String soapAction() const
bool getArg(const String &name, char &value, char defaultValue='?')
Definition: Envelope.h:202
Envelope & createResponse(const String &actionName)
Initialise the envelope as a response.
bool getArg(const String &name, double &value, double defaultValue=0.0)
Fault createFault(ErrorCode error)
Initialise the envelope as a fault.
String actionName() const
Get the action name.
Definition: Envelope.h:129
Represents any kind of device, including a root device.
Definition: UPnP/src/include/Network/UPnP/Service.h:47
Definition: WebConstants.h:72
Definition: ActionRequest.h:25
ErrorCode
Definition: ErrorCode.h:58
Error
Definition: Libraries/UPnP/src/include/Network/UPnP/Error.h:45
Node * getNode(Node *node, const char *path, const char *ns, size_t ns_len=0)
String getValue(const Node *node, const char *name, size_t name_size, const char *ns=nullptr, size_t ns_size=0)
rapidxml::xml_node< char > Node
Definition: RapidXML.h:37
rapidxml::xml_document< char > Document
Definition: RapidXML.h:36
Node * appendNode(Node *parent, const char *name, const char *value=nullptr, size_t name_size=0, size_t value_size=0)
Append a child element with optional value.
size_t serialize(const Node &node, String &buffer, bool pretty=false)
Serialize XML text and append to string buffer.
Definition: MPU6050.h:3441