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