[IoTConnectivity] Fix <code></code> as <example><code></code></example>
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.IoTConnectivity / Tizen.Network.IoTConnectivity / Attributes.cs
1  /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 using System;
19 using System.Collections;
20 using System.Collections.Generic;
21 using System.Runtime.InteropServices;
22
23 namespace Tizen.Network.IoTConnectivity
24 {
25     /// <summary>
26     /// This class represents current attributes of a resource.
27     /// It provides API to manage attributes.
28     /// This class is accessed by using a constructor to create a new instance of this object.
29     /// </summary>
30     /// <since_tizen> 3 </since_tizen>
31     public class Attributes : IDictionary<string, object>, IDisposable
32     {
33         internal IntPtr _resourceAttributesHandle = IntPtr.Zero;
34         private readonly IDictionary<string, object> _attributes = new Dictionary<string, object>();
35         private bool _disposed = false;
36
37         /// <summary>
38         /// The Attributes constructor.
39         /// </summary>
40         /// <since_tizen> 3 </since_tizen>
41         /// <feature>http://tizen.org/feature/iot.ocf</feature>
42         /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
43         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
44         /// <example><code>
45         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
46         /// </code></example>
47         public Attributes()
48         {
49             int ret = Interop.IoTConnectivity.Common.Attributes.Create(out _resourceAttributesHandle);
50             if (ret != (int)IoTConnectivityError.None)
51             {
52                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create attributes handle");
53                 throw IoTConnectivityErrorFactory.GetException(ret);
54             }
55         }
56
57         internal Attributes(IntPtr attributesHandleToClone)
58         {
59             int ret = Interop.IoTConnectivity.Common.Attributes.Clone(attributesHandleToClone, out _resourceAttributesHandle);
60             if (ret != (int)IoTConnectivityError.None)
61             {
62                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create attributes handle");
63                 throw IoTConnectivityErrorFactory.GetException(ret);
64             }
65
66             SetAttributes(_resourceAttributesHandle);
67         }
68
69         /// <summary>
70         /// Destructor of the Attributes class.
71         /// </summary>
72         ~Attributes()
73         {
74             Dispose(false);
75         }
76
77         /// <summary>
78         /// Gets the number of keys.
79         /// </summary>
80         /// <since_tizen> 3 </since_tizen>
81         /// <value>The number of keys.</value>
82         /// <example><code>
83         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
84         /// attributes.Add("brightness", 50);
85         /// var count = attributes.Count;
86         /// Console.WriteLine("There are {0} keys in the attribute object", count);
87         /// </code></example>
88         public int Count
89         {
90             get
91             {
92                 return _attributes.Count;
93             }
94         }
95
96         /// <summary>
97         /// Represents whether an attribute is readonly.
98         /// </summary>
99         /// <since_tizen> 3 </since_tizen>
100         /// <value>Whether an attribute is readonly.</value>
101         /// <example><code>
102         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
103         ///     { "state", "ON" },
104         ///     { "dim", 10 }
105         /// };
106         /// if (attributes.IsReadOnly)
107         ///     Console.WriteLine("Read only attribute");
108         /// </code></example>
109         public bool IsReadOnly
110         {
111             get
112             {
113                 return _attributes.IsReadOnly;
114             }
115         }
116
117         /// <summary>
118         /// Contains all the attribute keys.
119         /// </summary>
120         /// <since_tizen> 3 </since_tizen>
121         /// <value>All the attribute keys.</value>
122         /// <example><code>
123         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
124         ///     { "state", "ON" },
125         ///     { "dim", 10 }
126         /// };
127         /// var keys = attributes.Keys;
128         /// Console.WriteLine("Attribute contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1));
129         /// </code></example>
130         public ICollection<string> Keys
131         {
132             get
133             {
134                 return _attributes.Keys;
135             }
136         }
137
138         /// <summary>
139         /// Contains all the attribute values.
140         /// </summary>
141         /// <since_tizen> 3 </since_tizen>
142         /// <value>All the attribute values.</value>
143         /// <example><code>
144         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
145         ///     { "state", "ON" },
146         ///     { "dim", 10 }
147         /// };
148         /// var values = attributes.Values;
149         /// Console.WriteLine("Attribute contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1));
150         /// </code></example>
151         public ICollection<object> Values
152         {
153             get
154             {
155                 return _attributes.Values;
156             }
157         }
158
159         /// <summary>
160         /// Gets or sets the attribute with the specified key.
161         /// </summary>
162         /// <since_tizen> 3 </since_tizen>
163         /// <value>The attribute with the specified key.</value>
164         /// <param name="key">The key of the attribute to get or set.</param>
165         /// <returns>The element with the specified key.</returns>
166         /// <example><code>
167         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
168         /// attributes["state"] = "ON";
169         /// Console.WriteLine("Attribute value for key 'state' : {0}", attributes["state"]);
170         /// </code></example>
171         public object this[string key]
172         {
173             get
174             {
175                 if (_attributes.ContainsKey(key))
176                     return _attributes[key];
177                 else
178                     return null;
179             }
180
181             set
182             {
183                 Add(key, value);
184             }
185         }
186
187         /// <summary>
188         /// Adds the attribute key and a value as a key value pair.
189         /// </summary>
190         /// <since_tizen> 3 </since_tizen>
191         /// <param name="item">The key value pair to add.</param>
192         /// <feature>http://tizen.org/feature/iot.ocf</feature>
193         /// <example><code><![CDATA[
194         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
195         /// attributes.Add(new KeyValuePair<string, object> ("state", "ON"));
196         /// ]]></code></example>
197         public void Add(KeyValuePair<string, object> item)
198         {
199             Add(item.Key, item.Value);
200         }
201
202         /// <summary>
203         /// Adds an attribute.
204         /// </summary>
205         /// <since_tizen> 3 </since_tizen>
206         /// <param name="key">The key representing the attribute.</param>
207         /// <param name="value">The value representing the attribute.</param>
208         /// <feature>http://tizen.org/feature/iot.ocf</feature>
209         /// <example><code>
210         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
211         /// attributes.Add("brightness", 50);
212         /// </code></example>
213         public void Add(string key, object value)
214         {
215             int ret = 0;
216             if (value is int)
217             {
218                 ret = Interop.IoTConnectivity.Common.Attributes.AddInt(_resourceAttributesHandle, key, (int)value);
219                 if (ret != (int)IoTConnectivityError.None)
220                 {
221                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add int");
222                     throw IoTConnectivityErrorFactory.GetException(ret);
223                 }
224             }
225             else if (value is Attributes)
226             {
227                 Attributes attribs = (Attributes)value;
228                 ret = Interop.IoTConnectivity.Common.Attributes.AddAttributes(_resourceAttributesHandle, key, attribs._resourceAttributesHandle);
229                 if (ret != (int)IoTConnectivityError.None)
230                 {
231                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
232                     throw IoTConnectivityErrorFactory.GetException(ret);
233                 }
234             }
235             else if (value is string)
236             {
237                 ret = Interop.IoTConnectivity.Common.Attributes.AddStr(_resourceAttributesHandle, key, (string)value);
238                 if (ret != (int)IoTConnectivityError.None)
239                 {
240                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add string");
241                     throw IoTConnectivityErrorFactory.GetException(ret);
242                 }
243             }
244             else if (value is double)
245             {
246                 ret = Interop.IoTConnectivity.Common.Attributes.AddDouble(_resourceAttributesHandle, key, (double)value);
247                 if (ret != (int)IoTConnectivityError.None)
248                 {
249                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add double");
250                     throw IoTConnectivityErrorFactory.GetException(ret);
251                 }
252             }
253             else if (value is bool)
254             {
255                 ret = Interop.IoTConnectivity.Common.Attributes.AddBool(_resourceAttributesHandle, key, (bool)value);
256                 if (ret != (int)IoTConnectivityError.None)
257                 {
258                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
259                     throw IoTConnectivityErrorFactory.GetException(ret);
260                 }
261             }
262             else if (value is byte[])
263             {
264                 byte[] val = value as byte[];
265                 if (val == null)
266                 {
267                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get byte[] val");
268                     throw new ArgumentException("Invalid Parameter");
269                 }
270                 ret = Interop.IoTConnectivity.Common.Attributes.AddByteStr(_resourceAttributesHandle, key, val, val.Length);
271                 if (ret != (int)IoTConnectivityError.None)
272                 {
273                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
274                     throw IoTConnectivityErrorFactory.GetException(ret);
275                 }
276             }
277             else if (value is IEnumerable)
278             {
279                 IntPtr listHandle = List.GetListHandle(value);
280                 ret = Interop.IoTConnectivity.Common.Attributes.AddList(_resourceAttributesHandle, key, listHandle);
281                 if (ret != (int)IoTConnectivityError.None)
282                 {
283                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add list");
284                     throw IoTConnectivityErrorFactory.GetException(ret);
285                 }
286             }
287             else
288             {
289                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Add");
290                 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
291             }
292             _attributes.Add(key, value);
293         }
294
295         /// <summary>
296         /// Clears attributes collection.
297         /// </summary>
298         /// <since_tizen> 3 </since_tizen>
299         /// <feature>http://tizen.org/feature/iot.ocf</feature>
300         /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
301         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
302         /// <example><code>
303         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes();
304         /// attributes.Add("brightness", 50);
305         /// attributes.Clear();
306         /// </code></example>
307         public void Clear()
308         {
309             foreach (string key in _attributes.Keys)
310             {
311                 int ret = Interop.IoTConnectivity.Common.Attributes.Remove(_resourceAttributesHandle, key);
312                 if (ret != (int)IoTConnectivityError.None)
313                 {
314                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to clear attributes");
315                     throw IoTConnectivityErrorFactory.GetException(ret);
316                 }
317             }
318             _attributes.Clear();
319         }
320
321         /// <summary>
322         /// Checks whether the given key value pair exists in attributes collection.
323         /// </summary>
324         /// <since_tizen> 3 </since_tizen>
325         /// <param name="item">The status key value pair.</param>
326         /// <returns>true if exists. Otherwise, false.</returns>
327         /// <example><code><![CDATA[
328         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
329         ///     { "state", "ON" },
330         ///     { "dim", 10 }
331         /// };
332         /// if (attributes.Contains(new KeyValuePair<string, object> ("dim", 10))
333         ///     Console.WriteLine("Attribute conatins pair ('dim', 10)");
334         /// ]]></code></example>
335         public bool Contains(KeyValuePair<string, object> item)
336         {
337             return _attributes.Contains(item);
338         }
339
340         /// <summary>
341         /// Checks whether the given key exists in attributes collection.
342         /// </summary>
343         /// <since_tizen> 3 </since_tizen>
344         /// <param name="key">The status key to look for.</param>
345         /// <returns>true if exists. Otherwise, false.</returns>
346         /// <example><code>
347         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
348         ///     { "state", "ON" },
349         ///     { "dim", 10 }
350         /// };
351         /// if (attributes.ContainsKey("dim"))
352         ///     Console.WriteLine("Attribute conatins key : dim");
353         /// </code></example>
354         public bool ContainsKey(string key)
355         {
356             return _attributes.ContainsKey(key);
357         }
358
359         /// <summary>
360         /// Copies the elements of the attributes to an array, starting at a particular index.
361         /// </summary>
362         /// <since_tizen> 3 </since_tizen>
363         /// <param name="array">The destination array.</param>
364         /// <param name="arrayIndex">The zero-based index in an array at which copying begins.</param>
365         /// <example><code><![CDATA[
366         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
367         ///     { "state", "ON" },
368         ///     { "dim", 10 }
369         /// };
370         /// KeyValuePair<string, object>[] dest = new KeyValuePair<string, object>[attributes.Count];
371         /// int index = 0;
372         /// attributes.CopyTo(dest, index);
373         /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value);
374         /// ]]></code></example>
375         public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
376         {
377             _attributes.CopyTo(array, arrayIndex);
378         }
379
380         /// <summary>
381         /// Returns an enumerator that iterates through the collection.
382         /// </summary>
383         /// <since_tizen> 3 </since_tizen>
384         /// <returns> An enumerator that can be used to iterate through the collection.</returns>
385         /// <example><code><![CDATA[
386         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
387         ///     { "state", "ON" },
388         ///     { "dim", 10 }
389         /// };
390         /// foreach (KeyValuePair<string, object> pair in attributes)
391         /// {
392         ///     Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
393         /// }
394         /// ]]></code></example>
395         public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
396         {
397             return _attributes.GetEnumerator();
398         }
399
400         /// <summary>
401         /// Removes an attribute from collection.
402         /// </summary>
403         /// <since_tizen> 3 </since_tizen>
404         /// <param name="item">The attributes element to remove.</param>
405         /// <returns>true if operation is successful, otherwise, false.</returns>
406         /// <feature>http://tizen.org/feature/iot.ocf</feature>
407         /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
408         /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
409         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
410         /// <example><code><![CDATA[
411         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
412         ///     { "state", "ON" },
413         ///     { "dim", 10 }
414         /// };
415         /// if (attributes.Remove(new KeyValuePair<string, object>("dim", 10)))
416         ///     Console.WriteLine("Remove was successful");
417         /// ]]></code></example>
418         public bool Remove(KeyValuePair<string, object> item)
419         {
420             return Remove(item.Key);
421         }
422
423         /// <summary>
424         /// Removes an attribute from collection using a key.
425         /// </summary>
426         /// <since_tizen> 3 </since_tizen>
427         /// <param name="key">The attributes element to remove.</param>
428         /// <returns>true if operation is successful, otherwise, false.</returns>
429         /// <feature>http://tizen.org/feature/iot.ocf</feature>
430         /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
431         /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
432         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
433         /// <example><code>
434         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
435         ///     { "state", "ON" },
436         ///     { "dim", 10 }
437         /// };
438         /// if (attributes.Remove("state"))
439         ///     Console.WriteLine("Remove was successful");
440         /// </code></example>
441         public bool Remove(string key)
442         {
443             int ret = Interop.IoTConnectivity.Common.Attributes.Remove(_resourceAttributesHandle, key);
444             if (ret != (int)IoTConnectivityError.None)
445             {
446                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove attributes");
447                 throw IoTConnectivityErrorFactory.GetException(ret);
448             }
449
450             bool isRemoved = _attributes.Remove(key);
451
452             return isRemoved;
453         }
454
455         /// <summary>
456         /// Gets the value associated with the specified key.
457         /// </summary>
458         /// <since_tizen> 3 </since_tizen>
459         /// <param name="key">The key whose value to get.</param>
460         /// <param name="value"> The value associated with the specified key.</param>
461         /// <returns> true if the attributes collection contains an element with the specified key, otherwise, false.</returns>
462         /// <example><code>
463         /// Tizen.Network.IoTConnectivity.Attributes attributes = new Tizen.Network.IoTConnectivity.Attributes() {
464         ///     { "state", "ON" }
465         /// };
466         /// object value;
467         /// var isPresent = attributes.TryGetValue("state", out value);
468         /// if (isPresent)
469         ///     Console.WriteLine("value : {0}", value);
470         /// </code></example>
471         public bool TryGetValue(string key, out object value)
472         {
473             return _attributes.TryGetValue(key, out value);
474         }
475
476         /// <summary>
477         /// Returns an enumerator that iterates through the collection.
478         /// </summary>
479         /// <since_tizen> 3 </since_tizen>
480         IEnumerator IEnumerable.GetEnumerator()
481         {
482             return _attributes.GetEnumerator();
483         }
484
485         /// <summary>
486         /// Releases any unmanaged resources used by this object.
487         /// </summary>
488         /// <since_tizen> 3 </since_tizen>
489         /// <feature>http://tizen.org/feature/iot.ocf</feature>
490         public void Dispose()
491         {
492             Dispose(true);
493             GC.SuppressFinalize(this);
494         }
495
496         /// <summary>
497         /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
498         /// </summary>
499         /// <since_tizen> 3 </since_tizen>
500         /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
501         /// <feature>http://tizen.org/feature/iot.ocf</feature>
502         protected virtual void Dispose(bool disposing)
503         {
504             if (_disposed)
505                 return;
506
507             if (disposing)
508             {
509                 // Free managed objects
510             }
511
512             Interop.IoTConnectivity.Common.Attributes.Destroy(_resourceAttributesHandle);
513             _disposed = true;
514         }
515
516         private void SetAttributes(IntPtr attributesHandle)
517         {
518             Interop.IoTConnectivity.Common.Attributes.AttributesCallback cb = (IntPtr attributes, string key, IntPtr userData) =>
519             {
520                 Interop.IoTConnectivity.Common.DataType dataType;
521                 int ret = Interop.IoTConnectivity.Common.Attributes.GetType(attributes, key, out dataType);
522                 if (ret != (int)IoTConnectivityError.None)
523                 {
524                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
525                     throw IoTConnectivityErrorFactory.GetException(ret);
526                 }
527
528                 switch ((Interop.IoTConnectivity.Common.DataType)dataType)
529                 {
530                     case Interop.IoTConnectivity.Common.DataType.Int:
531                         {
532                             int value;
533                             ret = Interop.IoTConnectivity.Common.Attributes.GetInt(attributes, key, out value);
534                             if (ret != (int)IoTConnectivityError.None)
535                             {
536                                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
537                                 throw IoTConnectivityErrorFactory.GetException(ret);
538                             }
539                             _attributes.Add(key, value);
540                             break;
541                         }
542                     case Interop.IoTConnectivity.Common.DataType.Bool:
543                         {
544                             bool value;
545                             ret = Interop.IoTConnectivity.Common.Attributes.GetBool(attributes, key, out value);
546                             if (ret != (int)IoTConnectivityError.None)
547                             {
548                                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
549                                 throw IoTConnectivityErrorFactory.GetException(ret);
550                             }
551                             _attributes.Add(key, value);
552                             break;
553                         }
554                     case Interop.IoTConnectivity.Common.DataType.Double:
555                         {
556                             double value;
557                             ret = Interop.IoTConnectivity.Common.Attributes.GetDouble(attributes, key, out value);
558                             if (ret != (int)IoTConnectivityError.None)
559                             {
560                                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
561                                 throw IoTConnectivityErrorFactory.GetException(ret);
562                             }
563                             _attributes.Add(key, value);
564                             break;
565                         }
566                     case Interop.IoTConnectivity.Common.DataType.String:
567                         {
568                             IntPtr value;
569                             string Str;
570                             ret = Interop.IoTConnectivity.Common.Attributes.GetStr(attributes, key, out value);
571                             if (ret != (int)IoTConnectivityError.None)
572                             {
573                                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
574                                 throw IoTConnectivityErrorFactory.GetException(ret);
575                             }
576                             Str = (value != IntPtr.Zero) ? Marshal.PtrToStringAnsi(value) : string.Empty;
577                             _attributes.Add(key, Str);
578                             break;
579                         }
580                     case Interop.IoTConnectivity.Common.DataType.ByteStr:
581                         {
582                             IntPtr byteStrPtr;
583                             int byteStrSize;
584                             ret = Interop.IoTConnectivity.Common.Attributes.GetByteStr(attributes, key, out byteStrPtr, out byteStrSize);
585                             if (ret != (int)IoTConnectivityError.None)
586                             {
587                                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
588                                 throw IoTConnectivityErrorFactory.GetException(ret);
589                             }
590                             byte[] byteStr = new byte[byteStrSize];
591                             Marshal.Copy(byteStrPtr, byteStr, 0, byteStrSize);
592                             _attributes.Add(key, byteStr);
593                             break;
594                         }
595                     case Interop.IoTConnectivity.Common.DataType.Null:
596                         {
597                             _attributes.Add(key, null);
598                             break;
599                         }
600                     case Interop.IoTConnectivity.Common.DataType.List:
601                         {
602                             IntPtr listHandle;
603                             ret = Interop.IoTConnectivity.Common.Attributes.GetList(attributes, key, out listHandle);
604                             if (ret != (int)IoTConnectivityError.None)
605                             {
606                                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
607                                 throw IoTConnectivityErrorFactory.GetException(ret);
608                             }
609                             _attributes.Add(key, List.GetList(listHandle));
610                             break;
611                         }
612                     case Interop.IoTConnectivity.Common.DataType.Attributes:
613                         {
614                             IntPtr attribsHandle;
615                             ret = Interop.IoTConnectivity.Common.Attributes.GetAttributes(attributes, key, out attribsHandle);
616                             if (ret != (int)IoTConnectivityError.None)
617                             {
618                                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
619                                 throw IoTConnectivityErrorFactory.GetException(ret);
620                             }
621                             _attributes.Add(key, new Attributes(attribsHandle));
622                             break;
623                         }
624                     default:
625                         break;
626                 }
627
628                 return true;
629             };
630
631             int res = Interop.IoTConnectivity.Common.Attributes.Foreach(attributesHandle, cb, IntPtr.Zero);
632             if (res != (int)IoTConnectivityError.None)
633             {
634                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove attributes");
635                 throw IoTConnectivityErrorFactory.GetException(res);
636             }
637         }
638     }
639
640     internal static class List
641     {
642         internal static IntPtr GetListHandle(object list)
643         {
644             IntPtr listHandle = IntPtr.Zero;
645             int ret;
646             int pos = 0;
647
648             if (list is IEnumerable<IEnumerable>)
649             {
650                 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.List, out listHandle);
651                 pos = 0;
652                 foreach (IEnumerable val in (IEnumerable<IEnumerable>)list)
653                 {
654                     IntPtr childList = GetListHandle(val);
655                     ret = Interop.IoTConnectivity.Common.List.AddList(listHandle, childList, pos++);
656                     if (ret != (int)IoTConnectivityError.None)
657                     {
658                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
659                         Interop.IoTConnectivity.Common.List.Destroy(childList);
660                         throw IoTConnectivityErrorFactory.GetException(ret);
661                     }
662                 }
663             }
664             else if (list is IEnumerable<int>)
665             {
666                 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Int, out listHandle);
667                 pos = 0;
668                 foreach (int val in (IEnumerable<int>)list)
669                 {
670                     ret = Interop.IoTConnectivity.Common.List.AddInt(listHandle, val, pos++);
671                     if (ret != (int)IoTConnectivityError.None)
672                     {
673                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
674                         throw IoTConnectivityErrorFactory.GetException(ret);
675                     }
676                 }
677             }
678             else if (list is IEnumerable<string>)
679             {
680                 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.String, out listHandle);
681                 pos = 0;
682                 foreach (string val in (IEnumerable<string>)list)
683                 {
684                     ret = Interop.IoTConnectivity.Common.List.AddStr(listHandle, val, pos++);
685                     if (ret != (int)IoTConnectivityError.None)
686                     {
687                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add str");
688                         throw IoTConnectivityErrorFactory.GetException(ret);
689                     }
690                 }
691             }
692             else if (list is IEnumerable<double>)
693             {
694                 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Double, out listHandle);
695                 pos = 0;
696                 foreach (double val in (IEnumerable<double>)list)
697                 {
698                     ret = Interop.IoTConnectivity.Common.List.AddDouble(listHandle, val, pos++);
699                     if (ret != (int)IoTConnectivityError.None)
700                     {
701                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add double");
702                         throw IoTConnectivityErrorFactory.GetException(ret);
703                     }
704                 }
705             }
706             else if (list is IEnumerable<bool>)
707             {
708                 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Bool, out listHandle);
709                 pos = 0;
710                 foreach (bool val in (IEnumerable<bool>)list)
711                 {
712                     ret = Interop.IoTConnectivity.Common.List.AddBool(listHandle, val, pos++);
713                     if (ret != (int)IoTConnectivityError.None)
714                     {
715                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
716                         throw IoTConnectivityErrorFactory.GetException(ret);
717                     }
718                 }
719             }
720             else if (list is IEnumerable<Attributes>)
721             {
722                 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Attributes, out listHandle);
723                 pos = 0;
724                 foreach (Attributes val in (IEnumerable<Attributes>)list)
725                 {
726                     ret = Interop.IoTConnectivity.Common.List.AddAttributes(listHandle, val._resourceAttributesHandle, pos++);
727                     if (ret != (int)IoTConnectivityError.None)
728                     {
729                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
730                         throw IoTConnectivityErrorFactory.GetException(ret);
731                     }
732                 }
733             }
734             else if (list is IEnumerable<byte[]>)
735             {
736                 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.ByteStr, out listHandle);
737                 pos = 0;
738                 foreach (byte[] val in (IEnumerable<byte[]>)list)
739                 {
740                     ret = Interop.IoTConnectivity.Common.List.AddByteStr(listHandle, val, val.Length, pos++);
741                     if (ret != (int)IoTConnectivityError.None)
742                     {
743                         Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add byte[]");
744                         throw IoTConnectivityErrorFactory.GetException(ret);
745                     }
746                 }
747             }
748             else
749             {
750                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to GetListHandle");
751                 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
752             }
753             return listHandle;
754         }
755
756         internal static object GetList(IntPtr listHandle)
757         {
758             IList list = null;
759             int type;
760             int ret = Interop.IoTConnectivity.Common.List.GetType(listHandle, out type);
761             if (ret != (int)IoTConnectivityError.None)
762             {
763                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
764                 throw IoTConnectivityErrorFactory.GetException(ret);
765             }
766             switch ((Interop.IoTConnectivity.Common.DataType)type)
767             {
768                 case Interop.IoTConnectivity.Common.DataType.Int:
769                     {
770                         list = new List<int>();
771                         Interop.IoTConnectivity.Common.List.IntCallback cb = (int pos, int value, IntPtr userData) =>
772                         {
773                             list.Add(value);
774                             return true;
775                         };
776                         ret = Interop.IoTConnectivity.Common.List.ForeachInt(listHandle, cb, IntPtr.Zero);
777                         break;
778                     }
779                 case Interop.IoTConnectivity.Common.DataType.Bool:
780                     {
781                         list = new List<bool>();
782                         Interop.IoTConnectivity.Common.List.BoolCallback cb = (int pos, bool value, IntPtr userData) =>
783                         {
784                             list.Add(value);
785                             return true;
786                         };
787                         ret = Interop.IoTConnectivity.Common.List.ForeachBool(listHandle, cb, IntPtr.Zero);
788                         break;
789                     }
790                 case Interop.IoTConnectivity.Common.DataType.Double:
791                     {
792                         list = new List<double>();
793                         Interop.IoTConnectivity.Common.List.DoubleCallback cb = (int pos, double value, IntPtr userData) =>
794                         {
795                             list.Add(value);
796                             return true;
797                         };
798                         ret = Interop.IoTConnectivity.Common.List.ForeachDouble(listHandle, cb, IntPtr.Zero);
799                         break;
800                     }
801                 case Interop.IoTConnectivity.Common.DataType.String:
802                     {
803                         list = new List<string>();
804                         Interop.IoTConnectivity.Common.List.StrCallback cb = (int pos, string value, IntPtr userData) =>
805                         {
806                             list.Add(value);
807                             return true;
808                         };
809                         ret = Interop.IoTConnectivity.Common.List.ForeachStr(listHandle, cb, IntPtr.Zero);
810                         break;
811                     }
812                 case Interop.IoTConnectivity.Common.DataType.Attributes:
813                     {
814                         list = new List<Attributes>();
815                         Interop.IoTConnectivity.Common.List.AttribsCallback cb = (int pos, IntPtr value, IntPtr userData) =>
816                         {
817                             list.Add(new Attributes(value));
818                             return true;
819                         };
820                         ret = Interop.IoTConnectivity.Common.List.ForeachAttributes(listHandle, cb, IntPtr.Zero);
821                         break;
822                     }
823                 case Interop.IoTConnectivity.Common.DataType.ByteStr:
824                     {
825                         list = new List<byte[]>();
826                         Interop.IoTConnectivity.Common.List.ByteStrCallback cb = (int pos, byte[] value, int len, IntPtr userData) =>
827                         {
828                             list.Add(value);
829                             return true;
830                         };
831                         ret = Interop.IoTConnectivity.Common.List.ForeachByteStr(listHandle, cb, IntPtr.Zero);
832                         break;
833                     }
834                 case Interop.IoTConnectivity.Common.DataType.List:
835                     {
836                         list = new List<List<object>>();
837                         Interop.IoTConnectivity.Common.List.ListCallback cb = (int pos, IntPtr value, IntPtr userData) =>
838                         {
839                             object childList = GetList(value);
840                             if (childList != null)
841                                 list.Add(childList);
842                             return true;
843                         };
844                         ret = Interop.IoTConnectivity.Common.List.ForeachList(listHandle, cb, IntPtr.Zero);
845                         break;
846                     }
847                 default:
848                     break;
849             }
850             if (ret != (int)IoTConnectivityError.None)
851             {
852                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
853                 throw IoTConnectivityErrorFactory.GetException(ret);
854             }
855             return list;
856         }
857     }
858 }