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 /// State represents current state of a resource
19 public class State : IDictionary<string, object>, IDisposable
21 internal IntPtr _resourceStateHandle = IntPtr.Zero;
22 private readonly IDictionary<string, object> _state = new Dictionary<string, object>();
23 private bool _disposed = false;
30 int ret = Interop.IoTConnectivity.Common.State.Create(out _resourceStateHandle);
31 if (ret != (int)IoTConnectivityError.None)
33 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create state handle");
34 throw IoTConnectivityErrorFactory.GetException(ret);
38 internal State(IntPtr stateHandleToClone)
40 int ret = Interop.IoTConnectivity.Common.State.Clone(stateHandleToClone, out _resourceStateHandle);
41 if (ret != (int)IoTConnectivityError.None)
43 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create state handle");
44 throw IoTConnectivityErrorFactory.GetException(ret);
47 SetState(stateHandleToClone);
56 /// Gets the number of status elements
67 /// Represents whether State is readonly
69 public bool IsReadOnly
73 return _state.IsReadOnly;
78 /// Contains all the status keys
80 public ICollection<string> Keys
89 /// Contains all the status values
91 public ICollection<object> 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]
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 state</param>
130 /// <param name="value">The value representing the state</param>
131 public void Add(string key, object value)
136 ret = Interop.IoTConnectivity.Common.State.AddInt(_resourceStateHandle, 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 State)
145 State state = (State)value;
146 ret = Interop.IoTConnectivity.Common.State.AddState(_resourceStateHandle, key, state._resourceStateHandle);
147 if (ret != (int)IoTConnectivityError.None)
149 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state");
150 throw IoTConnectivityErrorFactory.GetException(ret);
153 else if (value is string)
155 ret = Interop.IoTConnectivity.Common.State.AddStr(_resourceStateHandle, 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.State.AddDouble(_resourceStateHandle, 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.State.AddBool(_resourceStateHandle, 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.State.AddByteStr(_resourceStateHandle, 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.State.AddList(_resourceStateHandle, key, listHandle);
199 Interop.IoTConnectivity.Common.State.Destroy(listHandle);
200 if (ret != (int)IoTConnectivityError.None)
202 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state");
203 throw IoTConnectivityErrorFactory.GetException(ret);
208 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to Add");
209 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
211 _state.Add(key, value);
215 /// Clears state collection
219 foreach (string key in _state.Keys)
221 int ret = Interop.IoTConnectivity.Common.State.Remove(_resourceStateHandle, key);
222 if (ret != (int)IoTConnectivityError.None)
224 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to clear state");
225 throw IoTConnectivityErrorFactory.GetException(ret);
232 /// Checks the given key value pair exists in state collection
234 /// <param name="item">The status key value pair</param>
235 /// <returns>true if exists. Otherwise, false</returns>
236 public bool Contains(KeyValuePair<string, object> item)
238 return _state.Contains(item);
242 /// Checks the given key exists in state collection
244 /// <param name="key">The status key</param>
245 /// <returns>true if exists. Otherwise, false</returns>
246 public bool ContainsKey(string key)
248 return _state.ContainsKey(key);
252 /// Copies the elements of the state to an Array, starting at a particular index.
254 /// <param name="array">The destination array</param>
255 /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
256 public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
258 _state.CopyTo(array, arrayIndex);
262 /// Returns an enumerator that iterates through the collection.
264 /// <returns> An enumerator that can be used to iterate through the collection.</returns>
265 public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
267 return _state.GetEnumerator();
271 /// Removes a state element from collection
273 /// <param name="item">The state element to remove</param>
274 /// <returns>true if operation is success. Otherwise, false</returns>
275 public bool Remove(KeyValuePair<string, object> item)
277 int ret = Interop.IoTConnectivity.Common.State.Remove(_resourceStateHandle, item.Key);
278 if (ret != (int)IoTConnectivityError.None)
280 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state");
281 throw IoTConnectivityErrorFactory.GetException(ret);
284 return _state.Remove(item);
288 /// Removes a state element from collection using key
290 /// <param name="key">The state element to remove</param>
291 /// <returns>true if operation is success. Otherwise, false</returns>
292 public bool Remove(string key)
294 int ret = Interop.IoTConnectivity.Common.State.Remove(_resourceStateHandle, key);
295 if (ret != (int)IoTConnectivityError.None)
297 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state");
298 throw IoTConnectivityErrorFactory.GetException(ret);
301 return _state.Remove(key);
305 /// Gets the value associated with the specified key.
307 /// <param name="key">The key whose value to get.</param>
308 /// <param name="value"> The value associated with the specified key</param>
309 /// <returns> true if the state collection contains an element with the specified key; otherwise, false.</returns>
310 public bool TryGetValue(string key, out object value)
312 return _state.TryGetValue(key, out value);
315 IEnumerator IEnumerable.GetEnumerator()
317 return _state.GetEnumerator();
320 public void Dispose()
323 GC.SuppressFinalize(this);
326 protected virtual void Dispose(bool disposing)
333 // Free managed objects
336 Interop.IoTConnectivity.Common.State.Destroy(_resourceStateHandle);
340 private void SetState(IntPtr stateHandle)
342 Interop.IoTConnectivity.Common.State.StateCallback cb = (IntPtr state, string key, IntPtr userData) =>
344 Interop.IoTConnectivity.Common.DataType type = 0;
345 int ret = Interop.IoTConnectivity.Common.State.GetType(state, key, out type);
346 if (ret != (int)IoTConnectivityError.None)
348 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
349 throw IoTConnectivityErrorFactory.GetException(ret);
353 case Interop.IoTConnectivity.Common.DataType.Int:
356 ret = Interop.IoTConnectivity.Common.State.GetInt(state, key, out value);
357 if (ret != (int)IoTConnectivityError.None)
359 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get state");
360 throw IoTConnectivityErrorFactory.GetException(ret);
365 case Interop.IoTConnectivity.Common.DataType.Bool:
368 ret = Interop.IoTConnectivity.Common.State.GetBool(state, key, out value);
369 if (ret != (int)IoTConnectivityError.None)
371 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get state");
372 throw IoTConnectivityErrorFactory.GetException(ret);
377 case Interop.IoTConnectivity.Common.DataType.Double:
380 ret = Interop.IoTConnectivity.Common.State.GetDouble(state, key, out value);
381 if (ret != (int)IoTConnectivityError.None)
383 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get state");
384 throw IoTConnectivityErrorFactory.GetException(ret);
389 case Interop.IoTConnectivity.Common.DataType.String:
392 ret = Interop.IoTConnectivity.Common.State.GetStr(state, key, out value);
393 if (ret != (int)IoTConnectivityError.None)
395 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get state");
396 throw IoTConnectivityErrorFactory.GetException(ret);
401 case Interop.IoTConnectivity.Common.DataType.ByteStr:
405 ret = Interop.IoTConnectivity.Common.State.GetByteStr(state, key, out byteStrPtr, out byteStrSize);
406 if (ret != (int)IoTConnectivityError.None)
408 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get state");
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.State.GetList(state, key, out listHandle);
425 if (ret != (int)IoTConnectivityError.None)
427 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get state");
428 throw IoTConnectivityErrorFactory.GetException(ret);
430 Add(key, List.GetList(listHandle));
433 case Interop.IoTConnectivity.Common.DataType.State:
436 ret = Interop.IoTConnectivity.Common.State.GetState(state, key, out stateHndle);
437 if (ret != (int)IoTConnectivityError.None)
439 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get state");
440 throw IoTConnectivityErrorFactory.GetException(ret);
442 Add(key, new State(stateHndle));
452 int res = Interop.IoTConnectivity.Common.State.Foreach(stateHandle, cb, IntPtr.Zero);
453 if (res != (int)IoTConnectivityError.None)
455 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove state");
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 state");
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 state");
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 state");
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 state");
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 state");
537 throw IoTConnectivityErrorFactory.GetException(ret);
541 else if (list is IEnumerable<State>)
543 ret = Interop.IoTConnectivity.Common.List.Create(Interop.IoTConnectivity.Common.DataType.State, out listHandle);
545 foreach (State val in (IEnumerable<State>)list)
547 ret = Interop.IoTConnectivity.Common.List.AddState(listHandle, val._resourceStateHandle, pos++);
548 if (ret != (int)IoTConnectivityError.None)
550 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add state");
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.State:
635 list = new List<State>();
636 Interop.IoTConnectivity.Common.List.StateCallback cb = (int pos, IntPtr value, IntPtr userData) =>
638 list.Add(new State(value));
641 ret = Interop.IoTConnectivity.Common.List.ForeachState(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 state");
673 throw IoTConnectivityErrorFactory.GetException(ret);