1 /// Copyright 2016 by Samsung Electronics, Inc.,
3 /// This software is the confidential and proprietary information
4 /// of Samsung Electronics, Inc. ("Confidential Information"). You
5 /// shall not disclose such Confidential Information and shall use
6 /// it only in accordance with the terms of the license agreement
7 /// you entered into with Samsung.
10 using System.Collections;
11 using System.Collections.Generic;
12 using System.Runtime.InteropServices;
14 namespace Tizen.Network.IoTConnectivity
17 /// This class represents current attributes of a resource.
19 public class Attributes : IDictionary<string, object>, IDisposable
21 internal IntPtr _resourceAttributesHandle = IntPtr.Zero;
22 private readonly IDictionary<string, object> _attributes = new Dictionary<string, object>();
23 private bool _disposed = false;
30 int ret = Interop.IoTConnectivity.Common.Attributes.Create(out _resourceAttributesHandle);
31 if (ret != (int)IoTConnectivityError.None)
33 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create attributes handle");
34 throw IoTConnectivityErrorFactory.GetException(ret);
38 internal Attributes(IntPtr attributesHandleToClone)
40 int ret = Interop.IoTConnectivity.Common.Attributes.Clone(attributesHandleToClone, out _resourceAttributesHandle);
41 if (ret != (int)IoTConnectivityError.None)
43 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create attributes handle");
44 throw IoTConnectivityErrorFactory.GetException(ret);
47 SetAttributes(attributesHandleToClone);
56 /// Gets the number of status elements
62 return _attributes.Count;
67 /// Represents whether Attributes is readonly
69 public bool IsReadOnly
73 return _attributes.IsReadOnly;
78 /// Contains all the status keys
80 public ICollection<string> Keys
84 return _attributes.Keys;
89 /// Contains all the status values
91 public ICollection<object> Values
95 return _attributes.Values;
100 /// Gets or sets the status with the specified key.
102 /// <param name="key">The key of the status to get or set.</param>
103 /// <returns>The element with the specified key.</returns>
104 public object this[string key]
108 return _attributes[key];
118 /// Adds status key and value as a key value pair
120 /// <param name="item">The item to add</param>
121 public void Add(KeyValuePair<string, object> item)
123 Add(item.Key, item.Value);
127 /// Adds status element
129 /// <param name="key">The key representing the attributes</param>
130 /// <param name="value">The value representing the attributes</param>
131 public void Add(string key, object value)
136 ret = Interop.IoTConnectivity.Common.Attributes.AddInt(_resourceAttributesHandle, key, (int)value);
137 if (ret != (int)IoTConnectivityError.None)
139 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add int");
140 throw IoTConnectivityErrorFactory.GetException(ret);
143 else if (value is Attributes)
145 Attributes attribs = (Attributes)value;
146 ret = Interop.IoTConnectivity.Common.Attributes.AddAttributes(_resourceAttributesHandle, key, attribs._resourceAttributesHandle);
147 if (ret != (int)IoTConnectivityError.None)
149 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
150 throw IoTConnectivityErrorFactory.GetException(ret);
153 else if (value is string)
155 ret = Interop.IoTConnectivity.Common.Attributes.AddStr(_resourceAttributesHandle, key, (string)value);
156 if (ret != (int)IoTConnectivityError.None)
158 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add string");
159 throw IoTConnectivityErrorFactory.GetException(ret);
162 else if (value is double)
164 ret = Interop.IoTConnectivity.Common.Attributes.AddDouble(_resourceAttributesHandle, key, (double)value);
165 if (ret != (int)IoTConnectivityError.None)
167 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add double");
168 throw IoTConnectivityErrorFactory.GetException(ret);
171 else if (value is bool)
173 ret = Interop.IoTConnectivity.Common.Attributes.AddBool(_resourceAttributesHandle, key, (bool)value);
174 if (ret != (int)IoTConnectivityError.None)
176 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
177 throw IoTConnectivityErrorFactory.GetException(ret);
180 else if (value is byte[])
182 byte[] val = value as byte[];
185 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get byte[] val");
186 throw new ArgumentException("Invalid Parameter");
188 ret = Interop.IoTConnectivity.Common.Attributes.AddByteStr(_resourceAttributesHandle, key, val, val.Length);
189 if (ret != (int)IoTConnectivityError.None)
191 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
192 throw IoTConnectivityErrorFactory.GetException(ret);
195 else if (value is IEnumerable)
197 IntPtr listHandle = List.GetListHandle(value);
198 ret = Interop.IoTConnectivity.Common.Attributes.AddList(_resourceAttributesHandle, key, listHandle);
199 if (ret != (int)IoTConnectivityError.None)
201 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add list");
202 throw IoTConnectivityErrorFactory.GetException(ret);
207 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Add");
208 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
210 _attributes.Add(key, value);
214 /// Clears attributes collection
218 foreach (string key in _attributes.Keys)
220 int ret = Interop.IoTConnectivity.Common.Attributes.Remove(_resourceAttributesHandle, key);
221 if (ret != (int)IoTConnectivityError.None)
223 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to clear attributes");
224 throw IoTConnectivityErrorFactory.GetException(ret);
231 /// Checks the given key value pair exists in attributes collection
233 /// <param name="item">The status key value pair</param>
234 /// <returns>true if exists. Otherwise, false</returns>
235 public bool Contains(KeyValuePair<string, object> item)
237 return _attributes.Contains(item);
241 /// Checks the given key exists in attributes collection
243 /// <param name="key">The status key</param>
244 /// <returns>true if exists. Otherwise, false</returns>
245 public bool ContainsKey(string key)
247 return _attributes.ContainsKey(key);
251 /// Copies the elements of the attributes to an Array, starting at a particular index.
253 /// <param name="array">The destination array</param>
254 /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
255 public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
257 _attributes.CopyTo(array, arrayIndex);
261 /// Returns an enumerator that iterates through the collection.
263 /// <returns> An enumerator that can be used to iterate through the collection.</returns>
264 public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
266 return _attributes.GetEnumerator();
270 /// Removes a attributes element from collection
272 /// <param name="item">The attributes element to remove</param>
273 /// <returns>true if operation is success. Otherwise, false</returns>
274 public bool Remove(KeyValuePair<string, object> item)
276 int ret = Interop.IoTConnectivity.Common.Attributes.Remove(_resourceAttributesHandle, item.Key);
277 if (ret != (int)IoTConnectivityError.None)
279 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove attributes");
280 throw IoTConnectivityErrorFactory.GetException(ret);
283 return _attributes.Remove(item);
287 /// Removes a attributes element from collection using key
289 /// <param name="key">The attributes element to remove</param>
290 /// <returns>true if operation is success. Otherwise, false</returns>
291 public bool Remove(string key)
293 int ret = Interop.IoTConnectivity.Common.Attributes.Remove(_resourceAttributesHandle, key);
294 if (ret != (int)IoTConnectivityError.None)
296 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove attributes");
297 throw IoTConnectivityErrorFactory.GetException(ret);
300 return _attributes.Remove(key);
304 /// Gets the value associated with the specified key.
306 /// <param name="key">The key whose value to get.</param>
307 /// <param name="value"> The value associated with the specified key</param>
308 /// <returns> true if the attributes collection contains an element with the specified key; otherwise, false.</returns>
309 public bool TryGetValue(string key, out object value)
311 return _attributes.TryGetValue(key, out value);
314 IEnumerator IEnumerable.GetEnumerator()
316 return _attributes.GetEnumerator();
319 public void Dispose()
322 GC.SuppressFinalize(this);
325 protected virtual void Dispose(bool disposing)
332 // Free managed objects
335 Interop.IoTConnectivity.Common.Attributes.Destroy(_resourceAttributesHandle);
339 private void SetAttributes(IntPtr attributesHandle)
341 Interop.IoTConnectivity.Common.Attributes.AttributesCallback cb = (IntPtr attributes, string key, IntPtr userData) =>
343 Interop.IoTConnectivity.Common.DataType dataType;
344 int ret = Interop.IoTConnectivity.Common.Attributes.GetType(attributes, key, out dataType);
345 if (ret != (int)IoTConnectivityError.None)
347 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
348 throw IoTConnectivityErrorFactory.GetException(ret);
351 switch ((Interop.IoTConnectivity.Common.DataType)dataType)
353 case Interop.IoTConnectivity.Common.DataType.Int:
356 ret = Interop.IoTConnectivity.Common.Attributes.GetInt(attributes, key, out value);
357 if (ret != (int)IoTConnectivityError.None)
359 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
360 throw IoTConnectivityErrorFactory.GetException(ret);
365 case Interop.IoTConnectivity.Common.DataType.Bool:
368 ret = Interop.IoTConnectivity.Common.Attributes.GetBool(attributes, key, out value);
369 if (ret != (int)IoTConnectivityError.None)
371 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
372 throw IoTConnectivityErrorFactory.GetException(ret);
377 case Interop.IoTConnectivity.Common.DataType.Double:
380 ret = Interop.IoTConnectivity.Common.Attributes.GetDouble(attributes, key, out value);
381 if (ret != (int)IoTConnectivityError.None)
383 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
384 throw IoTConnectivityErrorFactory.GetException(ret);
389 case Interop.IoTConnectivity.Common.DataType.String:
392 ret = Interop.IoTConnectivity.Common.Attributes.GetStr(attributes, key, out value);
393 if (ret != (int)IoTConnectivityError.None)
395 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
396 throw IoTConnectivityErrorFactory.GetException(ret);
401 case Interop.IoTConnectivity.Common.DataType.ByteStr:
405 ret = Interop.IoTConnectivity.Common.Attributes.GetByteStr(attributes, key, out byteStrPtr, out byteStrSize);
406 if (ret != (int)IoTConnectivityError.None)
408 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
409 throw IoTConnectivityErrorFactory.GetException(ret);
411 byte[] byteStr = new byte[byteStrSize];
412 Marshal.Copy(byteStrPtr, byteStr, 0, byteStrSize);
416 case Interop.IoTConnectivity.Common.DataType.Null:
421 case Interop.IoTConnectivity.Common.DataType.List:
424 ret = Interop.IoTConnectivity.Common.Attributes.GetList(attributes, key, out listHandle);
425 if (ret != (int)IoTConnectivityError.None)
427 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
428 throw IoTConnectivityErrorFactory.GetException(ret);
430 Add(key, List.GetList(listHandle));
433 case Interop.IoTConnectivity.Common.DataType.Attributes:
435 IntPtr attribsHandle;
436 ret = Interop.IoTConnectivity.Common.Attributes.GetAttributes(attributes, key, out attribsHandle);
437 if (ret != (int)IoTConnectivityError.None)
439 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
440 throw IoTConnectivityErrorFactory.GetException(ret);
442 Add(key, new Attributes(attribsHandle));
452 int res = Interop.IoTConnectivity.Common.Attributes.Foreach(attributesHandle, cb, IntPtr.Zero);
453 if (res != (int)IoTConnectivityError.None)
455 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove attributes");
456 throw IoTConnectivityErrorFactory.GetException(res);
461 internal static class List
463 internal static IntPtr GetListHandle(object list)
465 IntPtr listHandle = IntPtr.Zero;
469 if (list is IEnumerable<IEnumerable>)
471 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.List, out listHandle);
473 foreach (IEnumerable val in (IEnumerable<IEnumerable>)list)
475 IntPtr childList = GetListHandle(val);
476 ret = Interop.IoTConnectivity.Common.List.AddList(listHandle, childList, pos++);
477 if (ret != (int)IoTConnectivityError.None)
479 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
480 Interop.IoTConnectivity.Common.List.Destroy(childList);
481 throw IoTConnectivityErrorFactory.GetException(ret);
485 else if (list is IEnumerable<int>)
487 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Int, out listHandle);
489 foreach (int val in (IEnumerable<int>)list)
491 ret = Interop.IoTConnectivity.Common.List.AddInt(listHandle, val, pos++);
492 if (ret != (int)IoTConnectivityError.None)
494 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
495 throw IoTConnectivityErrorFactory.GetException(ret);
499 else if (list is IEnumerable<string>)
501 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.String, out listHandle);
503 foreach (string val in (IEnumerable<string>)list)
505 ret = Interop.IoTConnectivity.Common.List.AddStr(listHandle, val, pos++);
506 if (ret != (int)IoTConnectivityError.None)
508 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add str");
509 throw IoTConnectivityErrorFactory.GetException(ret);
513 else if (list is IEnumerable<double>)
515 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Double, out listHandle);
517 foreach (double val in (IEnumerable<double>)list)
519 ret = Interop.IoTConnectivity.Common.List.AddDouble(listHandle, val, pos++);
520 if (ret != (int)IoTConnectivityError.None)
522 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add double");
523 throw IoTConnectivityErrorFactory.GetException(ret);
527 else if (list is IEnumerable<bool>)
529 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Bool, out listHandle);
531 foreach (bool val in (IEnumerable<bool>)list)
533 ret = Interop.IoTConnectivity.Common.List.AddBool(listHandle, val, pos++);
534 if (ret != (int)IoTConnectivityError.None)
536 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add bool");
537 throw IoTConnectivityErrorFactory.GetException(ret);
541 else if (list is IEnumerable<Attributes>)
543 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.Attributes, out listHandle);
545 foreach (Attributes val in (IEnumerable<Attributes>)list)
547 ret = Interop.IoTConnectivity.Common.List.AddAttributes(listHandle, val._resourceAttributesHandle, pos++);
548 if (ret != (int)IoTConnectivityError.None)
550 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add attributes");
551 throw IoTConnectivityErrorFactory.GetException(ret);
555 else if (list is IEnumerable<byte[]>)
557 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.ByteStr, out listHandle);
559 foreach (byte[] val in (IEnumerable<byte[]>)list)
561 ret = Interop.IoTConnectivity.Common.List.AddByteStr(listHandle, val, val.Length, pos++);
562 if (ret != (int)IoTConnectivityError.None)
564 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add byte[]");
565 throw IoTConnectivityErrorFactory.GetException(ret);
571 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to GetListHandle");
572 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
577 internal static object GetList(IntPtr listHandle)
581 int ret = Interop.IoTConnectivity.Common.List.GetType(listHandle, out type);
582 if (ret != (int)IoTConnectivityError.None)
584 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
585 throw IoTConnectivityErrorFactory.GetException(ret);
587 switch ((Interop.IoTConnectivity.Common.DataType)type)
589 case Interop.IoTConnectivity.Common.DataType.Int:
591 list = new List<int>();
592 Interop.IoTConnectivity.Common.List.IntCallback cb = (int pos, int value, IntPtr userData) =>
597 ret = Interop.IoTConnectivity.Common.List.ForeachInt(listHandle, cb, IntPtr.Zero);
600 case Interop.IoTConnectivity.Common.DataType.Bool:
602 list = new List<bool>();
603 Interop.IoTConnectivity.Common.List.BoolCallback cb = (int pos, bool value, IntPtr userData) =>
608 ret = Interop.IoTConnectivity.Common.List.ForeachBool(listHandle, cb, IntPtr.Zero);
611 case Interop.IoTConnectivity.Common.DataType.Double:
613 list = new List<double>();
614 Interop.IoTConnectivity.Common.List.DoubleCallback cb = (int pos, double value, IntPtr userData) =>
619 ret = Interop.IoTConnectivity.Common.List.ForeachDouble(listHandle, cb, IntPtr.Zero);
622 case Interop.IoTConnectivity.Common.DataType.String:
624 list = new List<string>();
625 Interop.IoTConnectivity.Common.List.StrCallback cb = (int pos, string value, IntPtr userData) =>
630 ret = Interop.IoTConnectivity.Common.List.ForeachStr(listHandle, cb, IntPtr.Zero);
633 case Interop.IoTConnectivity.Common.DataType.Attributes:
635 list = new List<Attributes>();
636 Interop.IoTConnectivity.Common.List.AttribsCallback cb = (int pos, IntPtr value, IntPtr userData) =>
638 list.Add(new Attributes(value));
641 ret = Interop.IoTConnectivity.Common.List.ForeachAttributes(listHandle, cb, IntPtr.Zero);
644 case Interop.IoTConnectivity.Common.DataType.ByteStr:
646 list = new List<byte[]>();
647 Interop.IoTConnectivity.Common.List.ByteStrCallback cb = (int pos, byte[] value, int len, IntPtr userData) =>
652 ret = Interop.IoTConnectivity.Common.List.ForeachByteStr(listHandle, cb, IntPtr.Zero);
655 case Interop.IoTConnectivity.Common.DataType.List:
657 list = new List<List<object>>();
658 Interop.IoTConnectivity.Common.List.ListCallback cb = (int pos, IntPtr value, IntPtr userData) =>
660 object childList = GetList(value);
664 ret = Interop.IoTConnectivity.Common.List.ForeachList(listHandle, cb, IntPtr.Zero);
670 if (ret != (int)IoTConnectivityError.None)
672 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get attributes");
673 throw IoTConnectivityErrorFactory.GetException(ret);