/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Tizen.Network.IoTConnectivity { /// /// This class represents resource options. It provides APIs to manage them.\n /// The iotcon options API provides methods for managing vendor specific options of coap packet.\n /// See more about coap packet in http://tools.ietf.org/html/rfc7252. /// /// 3 public class ResourceOptions : IDictionary, IDisposable { internal const int MaxSize = 2; internal const int IdMin = 2048; internal const int IdMax = 3000; internal const int DataMax = 15; internal IntPtr _resourceOptionsHandle = IntPtr.Zero; private readonly IDictionary _options = new Dictionary(); private bool _disposed = false; /// /// The resource options constructor. /// /// 3 /// http://tizen.org/feature/iot.ocf /// /// /// Thrown when the iotcon is not supported. /// Thrown when there is not enough memory. /// /// ResourceOptions options = new ResourceOptions(); /// public ResourceOptions() { int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options"); throw IoTConnectivityErrorFactory.GetException(ret); } } // internal constructor internal ResourceOptions(IntPtr handleToClone) { int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options"); throw IoTConnectivityErrorFactory.GetException(ret); } Interop.IoTConnectivity.Common.Options.OptionsCallback forEachCallback = (ushort id, string value, IntPtr userData) => { Add(id, value); return true; }; ret = Interop.IoTConnectivity.Common.Options.ForEach(handleToClone, forEachCallback, IntPtr.Zero); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to iterate options"); throw IoTConnectivityErrorFactory.GetException(ret); } } /// /// Destructor of the ResourceOptions class. /// ~ResourceOptions() { Dispose(false); } /// /// Contains all the Option keys. /// /// 3 /// All the Option keys. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(2050, "sample-data"); /// options.Add(2055, "sample value"); /// var keys = options.Keys; /// Console.WriteLine("Resource options contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1)); /// public ICollection Keys { get { return _options.Keys; } } /// /// Contains all the Option values. /// /// 3 /// All the Option values. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(2050, "sample-data"); /// options.Add(2055, "sample value"); /// var values = options.Values; /// Console.WriteLine("Resource options contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1)); /// public ICollection Values { get { return _options.Values; } } /// /// Gets the number of options. /// /// 3 /// The number of options. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(2050, "sample-data"); /// options.Add(2055, "sample value"); /// var count = options.Count; /// Console.WriteLine("There are {0} keys in the options object", count); /// public int Count { get { return _options.Count; } } /// /// Represents whether the collection is readonly. /// /// 3 /// Whether the collection is readonly. /// /// ResourceOptions options = new ResourceOptions(); /// if (options.IsReadOnly) /// Console.WriteLine("Read only options"); /// public bool IsReadOnly { get { return _options.IsReadOnly; } } /// /// Gets or sets the option data. /// /// 3 /// The option data. /// The option ID to get or set. /// The option with the specified ID. /// /// ResourceOptions options = new ResourceOptions(); /// options[2055] = "sample-data"; /// Console.WriteLine("Option has : {0}", options[2055]); /// public string this[ushort key] { get { return _options[key]; } set { Add(key, value); } } /// /// Checks whether the given key exists in Options collection. /// /// 3 /// The key to look for. /// true if exists. Otherwise, false. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(2050, "sample-data"); /// if (options.ContainsKey(2050)) /// Console.WriteLine("options conatins key : 2050"); /// public bool ContainsKey(ushort key) { return _options.ContainsKey(key); } /// /// Adds a new ID and a correspoding data into the options. /// /// 3 /// /// ResourceOptions can have up to 2 options. \n /// key is always situated between 2048 and 3000. \n /// Length of option data is less than or equal to 15. /// /// The ID of the option to insert. /// The string data to insert into the options. /// http://tizen.org/feature/iot.ocf /// /// Thrown when the iotcon is not supported. /// Thrown when there is an invalid parameter. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(2050, "sample-data"); /// public void Add(ushort key, string value) { int ret = (int)IoTConnectivityError.InvalidParameter; if (IsValid(key, value)) { ret = Interop.IoTConnectivity.Common.Options.Add(_resourceOptionsHandle, key, value); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add option"); throw IoTConnectivityErrorFactory.GetException(ret); } _options.Add(key, value); } else { Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid options"); throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter); } } /// /// Removes the ID and its associated data from the options. /// /// 3 /// The ID of the option to delete. /// True if operation is successful. Otherwise, false. /// http://tizen.org/feature/iot.ocf /// /// Thrown when the iotcon is not supported. /// Thrown when there is an invalid parameter. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(2050, "12345"); /// var result = options.Remove(2050); /// public bool Remove(ushort key) { int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option"); throw IoTConnectivityErrorFactory.GetException(ret); } bool isRemoved = _options.Remove(key); return isRemoved; } /// /// Gets the value associated with the specified key. /// /// 3 /// The option ID. /// Value corresponding to option ID. /// True if the key exists, false otherwise. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(2050, "12345"); /// string value; /// var isPresent = options.TryGetValue(2050, out value); /// if (isPresent) /// Console.WriteLine("value : {0}", value); /// public bool TryGetValue(ushort key, out string value) { return _options.TryGetValue(key, out value); } /// /// Adds options key and value as a key value pair. /// /// 3 /// The key value pair. /// http://tizen.org/feature/iot.ocf /// /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(new KeyValuePair(2050, "12345")); /// public void Add(KeyValuePair item) { Add(item.Key, item.Value); } /// /// Clears the Options collection. /// /// 3 /// http://tizen.org/feature/iot.ocf /// Thrown when the iotcon is not supported. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(2050, "12345"); /// options.Add(2055, "sample"); /// options.Clear(); /// public void Clear() { foreach (ushort key in Keys) { int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option"); throw IoTConnectivityErrorFactory.GetException(ret); }; } _options.Clear(); } /// /// Checks if the given option pair exists. /// /// 3 /// The key value pair. /// True if exists. Otherwise, false. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(new KeyValuePair(2050, "12345")); /// var isPresent = options.Contains(new KeyValuePair(2050, "12345")); /// if (isPresent) /// Console.WriteLine("Key value pair is present"); /// public bool Contains(KeyValuePair item) { return _options.Contains(item); } /// /// Copies the elements of the options collection to an array, starting at a particular index. /// /// 3 /// The destination array. /// Index parameter. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(new KeyValuePair(2050, "12345")); /// KeyValuePair[] dest = new KeyValuePair[options.Count]; /// options.CopyTo(dest, 0); /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value); /// public void CopyTo(KeyValuePair[] array, int arrayIndex) { _options.CopyTo(array, arrayIndex); } /// /// Removes the given key value pair from the options. /// /// 3 /// The key value pair to remove /// True if operation is successful. Otherwise, false /// http://tizen.org/feature/iot.ocf /// /// Thrown when there is an invalid parameter /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(new KeyValuePair(2050, "12345")); /// var result = options.Remove(new KeyValuePair(2050, "12345")); /// public bool Remove(KeyValuePair item) { return Remove(item.Key); } /// /// Get the enumerator to options collection. /// /// 3 /// Enumerator to option pairs. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(new KeyValuePair(2050, "sample1")); /// options.Add(new KeyValuePair(2055, "sample2")); /// foreach (KeyValuePair pair in options) /// { /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value); /// } /// public IEnumerator> GetEnumerator() { return _options.GetEnumerator(); } /// /// Releases any unmanaged resources used by this object. /// /// 3 /// http://tizen.org/feature/iot.ocf public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Gets the enumerator to options collection. /// /// 3 /// Enumerator to option pairs. /// /// ResourceOptions options = new ResourceOptions(); /// options.Add(new KeyValuePair(2050, "sample1")); /// options.Add(new KeyValuePair(2055, "sample2")); /// foreach (KeyValuePair pair in options) /// { /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value); /// } /// IEnumerator IEnumerable.GetEnumerator() { return _options.GetEnumerator(); } /// /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects. /// /// 3 /// If true, disposes any disposable objects. If false, does not dispose disposable objects. /// http://tizen.org/feature/iot.ocf protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { // Free managed objects } Interop.IoTConnectivity.Common.Options.Destroy(_resourceOptionsHandle); _disposed = true; } private bool IsValid(ushort key, string value) { return (key > IdMin && key < IdMax && value.Length <= DataMax && _options.Count() < MaxSize); } } }