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