Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
UPnPStateVariable.cs
1using System;
3using System.Globalization;
4using System.Text;
5using System.Threading.Tasks;
6using System.Xml;
7using Waher.Content;
8
10{
14 public class UPnPStateVariable
15 {
16 private readonly XmlElement xml;
17 private readonly string[] allowedValues;
18 private readonly string name;
19 private readonly string dataType;
20 private readonly string defaultValue;
21 private readonly string minimum;
22 private readonly string maximum;
23 private readonly string step;
24 private readonly bool sendsEvents;
25 private readonly bool hasAllowedValues = false;
26 private readonly bool hasAllowedValueRange = false;
27
28 internal UPnPStateVariable(XmlElement Xml)
29 {
30 List<string> AllowedValues = new List<string>();
31
32 this.xml = Xml;
33
34 this.sendsEvents = (Xml.HasAttribute("sendEvents") && Xml.GetAttribute("sendEvents") == "yes");
35
36 foreach (XmlNode N in Xml.ChildNodes)
37 {
38 switch (N.LocalName)
39 {
40 case "name":
41 this.name = N.InnerText;
42 break;
43
44 case "dataType":
45 this.dataType = N.InnerText;
46 break;
47
48 case "defaultValue":
49 this.defaultValue = N.InnerText;
50 break;
51
52 case "allowedValueList":
53 this.hasAllowedValues = true;
54 foreach (XmlNode N2 in N.ChildNodes)
55 {
56 if (N2.LocalName == "allowedValue")
57 AllowedValues.Add(N2.InnerText);
58 }
59 break;
60
61 case "allowedValueRange":
62 this.hasAllowedValueRange = true;
63 foreach (XmlNode N2 in N.ChildNodes)
64 {
65 switch (N2.LocalName)
66 {
67 case "minimum":
68 this.minimum = N2.InnerText;
69 break;
70
71 case "maximum":
72 this.maximum = N2.InnerText;
73 break;
74
75 case "step":
76 this.step = N2.InnerText;
77 break;
78 }
79 }
80 break;
81 }
82 }
83
84 this.allowedValues = AllowedValues.ToArray();
85 }
86
90 public XmlElement Xml => this.xml;
91
95 public string Name => this.name;
96
100 public string DataType => this.dataType;
101
105 public string DefaultValue => this.defaultValue;
106
110 public bool SendsEvents => this.sendsEvents;
111
115 public string[] AllowedValues => this.allowedValues;
116
120 public bool HasAllowedValues => this.hasAllowedValues;
121
125 public bool HasAllowedValueRange => this.hasAllowedValueRange;
126
130 public string Minimum => this.minimum;
131
135 public string Maximum => this.maximum;
136
140 public string Step => this.step;
141
147 public async Task<string> ValueToXmlString(object Value)
148 {
149 switch (this.dataType)
150 {
151 case "ui1":
152 case "ui2":
153 case "ui4":
154 case "i1":
155 case "i2":
156 case "i4":
157 case "int":
158 case "char":
159 case "string":
160 case "uri":
161 case "uuid":
162 default:
163 return Value.ToString();
164
165 case "r4":
166 case "r8":
167 case "number":
168 case "float":
169 if (!(Value is double d))
170 {
171 if (Value is float f)
172 d = f;
173 else if (Value is decimal dec)
174 d = (double)dec;
175 else
176 d = Convert.ToDouble(Value);
177 }
178
179 return d.ToString(CultureInfo.InvariantCulture);
180
181 case "fixed.14.4":
182
183 if (Value is double d2)
184 d = d2;
185 else if (Value is float f2)
186 d = f2;
187 else if (Value is decimal dec2)
188 d = (double)dec2;
189 else
190 d = Convert.ToDouble(Value);
191
192 return d.ToString("F4", CultureInfo.InvariantCulture);
193
194 case "date":
195 if (!(Value is DateTime DT))
196 DT = Convert.ToDateTime(Value);
197
198 return DT.ToString("yyyyMMdd");
199
200 case "dateTime":
201 if (!(Value is DateTime DT2))
202 DT2 = Convert.ToDateTime(Value);
203
204 return DT2.ToString("yyyyMMddTHHmmss");
205
206 case "dateTime.tz":
207 if (Value is DateTimeOffset DTO)
208 {
209 string s = DTO.ToString("yyyyMMddTHHmmss");
210 TimeSpan Zone = DTO.Offset;
211
212 if (Zone < TimeSpan.Zero)
213 {
214 s += "-";
215 Zone = -Zone;
216 }
217 else
218
219 s += "+";
220
221 return s + Zone.Hours.ToString("D2") + ":" + Zone.Minutes.ToString("D2");
222 }
223 else
224 {
225 if (!(Value is DateTime DT3))
226 DT3 = Convert.ToDateTime(Value);
227
228 return DT3.ToString("yyyyMMddTHHmmss");
229 }
230
231 case "time":
232 if (Value is TimeSpan TS)
233 return TS.Hours.ToString("D2") + ":" + TS.Minutes.ToString("D2") + ":" + TS.Seconds.ToString("D2");
234 else if (Value is DateTime DT4)
235 return DT4.ToString("HH:mm:ss");
236 else if (TimeSpan.TryParse(Value.ToString(), out TS))
237 return TS.Hours.ToString("D2") + ":" + TS.Minutes.ToString("D2") + ":" + TS.Seconds.ToString("D2");
238 else
239 {
240 DT = Convert.ToDateTime(Value);
241 return DT.ToString("HH:mm:ss");
242 }
243
244 case "time.tz":
245 if (Value is TimeSpan TS2)
246 return TS2.Hours.ToString("D2") + ":" + TS2.Minutes.ToString("D2") + ":" + TS2.Seconds.ToString("D2");
247 else if (Value is DateTime DT5)
248 return DT5.ToString("HH:mm:ss");
249 else if (Value is DateTimeOffset DTO2)
250 {
251 string s = DTO2.ToString("HH:mm:ss");
252 TimeSpan Zone = DTO2.Offset;
253
254 if (Zone < TimeSpan.Zero)
255 {
256 s += "-";
257 Zone = -Zone;
258 }
259 else
260
261 s += "+";
262
263 return s + Zone.Hours.ToString("D2") + ":" + Zone.Minutes.ToString("D2");
264 }
265 else if (TimeSpan.TryParse(Value.ToString(), out TS))
266 return TS.Hours.ToString("D2") + ":" + TS.Minutes.ToString("D2") + ":" + TS.Seconds.ToString("D2");
267 else
268 {
269 DT = Convert.ToDateTime(Value);
270 return DT.ToString("HH:mm:ss");
271 }
272
273 case "boolean":
274 if (!(Value is bool b))
275 b = Convert.ToBoolean(Value);
276
277 return b ? "1" : "0";
278
279 case "bin.base64":
280 if (!(Value is byte[] Bin))
281 Bin = await SerializeToBinary(Value);
282
283 return Convert.ToBase64String(Bin);
284
285 case "bin.hex":
286 if (!(Value is byte[] Bin2))
287 Bin2 = await SerializeToBinary(Value);
288
289 StringBuilder sb = new StringBuilder();
290
291 foreach (byte b2 in Bin2)
292 sb.Append(b2.ToString("X2"));
293
294 return sb.ToString();
295 }
296 }
297
303 public object XmlStringToValue(string Value)
304 {
305 switch (this.dataType)
306 {
307 case "ui1":
308 return byte.Parse(Value);
309
310 case "ui2":
311 return ushort.Parse(Value);
312
313 case "ui4":
314 return uint.Parse(Value);
315
316 case "i1":
317 return sbyte.Parse(Value);
318
319 case "i2":
320 return short.Parse(Value);
321
322 case "i4":
323 return int.Parse(Value);
324
325 case "int":
326 return long.Parse(Value);
327
328 case "char":
329 return Value[0];
330
331 case "string":
332 return Value;
333
334 case "uri":
335 return new Uri(Value);
336
337 case "uuid":
338 return new Guid(Value);
339
340 case "r4":
341 return float.Parse(Value.Replace(".", System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator));
342
343 case "r8":
344 case "number":
345 case "float":
346 case "fixed.14.4":
347 return double.Parse(Value.Replace(".", System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator));
348
349 case "date":
350 return DateTime.Parse(Value);
351
352 case "dateTime":
353 return DateTime.Parse(Value.Replace("T", " "));
354
355 case "dateTime.tz":
356 return DateTimeOffset.Parse(Value.Replace("T", " "));
357
358 case "time":
359 case "time.tz":
360 return TimeSpan.Parse(Value.Replace("T", " "));
361
362 case "boolean":
363 Value = Value.ToLower();
364 return (Value == "1" || Value == "true" || Value == "yes");
365
366 case "bin.base64":
367 return Convert.FromBase64String(Value);
368
369 case "bin.hex":
370 int i, c = Value.Length;
371 if ((c & 1) == 1)
372 throw new Exception("Invalid bin.hex value");
373
374 byte[] Bin = new byte[c / 2];
375 int j;
376 byte b;
377 char ch;
378
379 for (i = j = 0; i < c;)
380 {
381 ch = Value[i++];
382
383 if (ch >= '0' && ch <= '9')
384 b = (byte)(ch - '0');
385 else if (ch >= 'A' && ch <= 'F')
386 b = (byte)(ch - 'A' + 10);
387 else if (ch >= 'a' && ch <= 'f')
388 b = (byte)(ch - 'a' + 10);
389 else
390 throw new Exception("Invalid bin.hex value");
391
392 b <<= 4;
393 ch = Value[i++];
394
395 if (ch >= '0' && ch <= '9')
396 b |= (byte)(ch - '0');
397 else if (ch >= 'A' && ch <= 'F')
398 b |= (byte)(ch - 'A' + 10);
399 else if (ch >= 'a' && ch <= 'f')
400 b |= (byte)(ch - 'a' + 10);
401 else
402 throw new Exception("Invalid bin.hex value");
403
404 Bin[j++] = b;
405 }
406
407 return Bin;
408
409 default:
410 return Value;
411 }
412 }
413
419 public static async Task<byte[]> SerializeToBinary(object Value)
420 {
421 if (Value is byte[] Bin)
422 return Bin;
423 else
424 {
425 ContentResponse P = await InternetContent.EncodeAsync(Value, Encoding.UTF8);
426 P.AssertOk();
427
428 return P.Encoded;
429 }
430 }
431 }
432}
Contains information about a response to a content request.
byte[] Encoded
Encoded object.
void AssertOk()
Asserts response is OK.
Static class managing encoding and decoding of internet content.
static Task< ContentResponse > EncodeAsync(object Object, Encoding Encoding, params string[] AcceptedContentTypes)
Encodes an object.
Contains information about a state variable.
static async Task< byte[]> SerializeToBinary(object Value)
Serializes an object to an array of bytes.
string Minimum
Smallest value allowed. Provided if HasAllowedValueRange is true.
bool HasAllowedValueRange
If Minimum, Maximum and Step defines a range of allowed values.
object XmlStringToValue(string Value)
Converts a value from its XML string representation to an object value with the correct type.
string Maximum
Largest value allowed. Provided if HasAllowedValueRange is true.
XmlElement Xml
Underlying XML definition.
bool HasAllowedValues
If AllowedValues contains a list of allowed values.
async Task< string > ValueToXmlString(object Value)
Converts a value to its XML string representation.
bool SendsEvents
If state variable sends events.
string Step
Step value. Provided if HasAllowedValueRange is true.
string[] AllowedValues
List of allowed values. Provided if HasAllowedValues is true.