2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Collections;
20 using System.Collections.Generic;
23 namespace Tizen.Network.IoTConnectivity
26 /// This class represents resource options. It provides APIs to manage them.\n
27 /// The iotcon options API provides methods for managing vendor specific options of coap packet.\n
28 /// See more about coap packet in http://tools.ietf.org/html/rfc7252.
30 public class ResourceOptions : IDictionary<ushort, string>, IDisposable
32 internal const int MaxSize = 2;
33 internal const int IdMin = 2048;
34 internal const int IdMax = 3000;
35 internal const int DataMax = 15;
37 internal IntPtr _resourceOptionsHandle = IntPtr.Zero;
38 private readonly IDictionary<ushort, string> _options = new Dictionary<ushort, string>();
39 private bool _disposed = false;
42 /// The resource options constructor
44 /// <seealso cref="Add()"/>
45 /// <seealso cref="Remove()"/>
46 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
47 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
48 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
50 /// ResourceOptions options = new ResourceOptions();
52 public ResourceOptions()
54 int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle);
55 if (ret != (int)IoTConnectivityError.None)
57 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options");
58 throw IoTConnectivityErrorFactory.GetException(ret);
62 // internal constructor
63 internal ResourceOptions(IntPtr handleToClone)
65 int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle);
66 if (ret != (int)IoTConnectivityError.None)
68 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options");
69 throw IoTConnectivityErrorFactory.GetException(ret);
72 Interop.IoTConnectivity.Common.Options.OptionsCallback forEachCallback = (ushort id, string value, IntPtr userData) =>
78 ret = Interop.IoTConnectivity.Common.Options.ForEach(handleToClone, forEachCallback, IntPtr.Zero);
79 if (ret != (int)IoTConnectivityError.None)
81 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to iterate options");
82 throw IoTConnectivityErrorFactory.GetException(ret);
87 /// Destructor of the ResourceOptions class.
95 /// Contains all the Option keys
98 /// ResourceOptions options = new ResourceOptions();
99 /// options.Add(2050, "sample-data");
100 /// options.Add(2055, "sample value");
101 /// var keys = options.Keys;
102 /// Console.WriteLine("Resource options contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1));
104 public ICollection<ushort> Keys
108 return _options.Keys;
113 /// Contains all the Option values
116 /// ResourceOptions options = new ResourceOptions();
117 /// options.Add(2050, "sample-data");
118 /// options.Add(2055, "sample value");
119 /// var values = options.Values;
120 /// Console.WriteLine("Resource options contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1));
122 public ICollection<string> Values
126 return _options.Values;
131 /// Gets the number of options
134 /// ResourceOptions options = new ResourceOptions();
135 /// options.Add(2050, "sample-data");
136 /// options.Add(2055, "sample value");
137 /// var count = options.Count;
138 /// Console.WriteLine("There are {0} keys in the options object", count);
144 return _options.Count;
149 /// Gets or sets the option data
152 /// <param name="key">The option id to get or set.</param>
153 /// <returns>The option with the specified id.</returns>
155 /// ResourceOptions options = new ResourceOptions();
156 /// options[2055] = "sample-data";
157 /// Console.WriteLine("Option has : {0}", options[2055]);
159 public string this[ushort key]
163 return _options[key];
172 /// Checks whether the given key exists in Options collection
174 /// <param name="key">The key to look for</param>
175 /// <returns>true if exists. Otherwise, false</returns>
177 /// ResourceOptions options = new ResourceOptions();
178 /// options.Add(2050, "sample-data");
179 /// if (options.ContainsKey(2050))
180 /// Console.WriteLine("options conatins key : 2050");
182 public bool ContainsKey(ushort key)
184 return _options.ContainsKey(key);
188 /// Adds a new id and a correspoding data into the options.
191 /// ResourceOptions can have up to 2 options. \n
192 /// key is always situated between 2048 and 3000. \n
193 /// Length of option data is less than or equal to 15.
195 /// <param name="key">The id of the option to insert</param>
196 /// <param name="value">The string data to insert into the options</param>
197 /// <seealso cref="Remove()"/>
198 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
199 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
201 /// ResourceOptions options = new ResourceOptions();
202 /// options.Add(2050, "sample-data");
204 public void Add(ushort key, string value)
206 int ret = (int)IoTConnectivityError.InvalidParameter;
207 if (IsValid(key, value))
209 ret = Interop.IoTConnectivity.Common.Options.Add(_resourceOptionsHandle, key, value);
210 if (ret != (int)IoTConnectivityError.None)
212 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add option");
213 throw IoTConnectivityErrorFactory.GetException(ret);
215 _options.Add(key, value);
219 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid options");
220 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
225 /// Removes the id and its associated data from the options.
227 /// <param name="key">The id of the option to delete</param>
228 /// <returns>True if operation is successful. Otherwise, false</returns>
229 /// <seealso cref="Add()"/>
230 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
231 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
233 /// ResourceOptions options = new ResourceOptions();
234 /// options.Add(2050, "12345");
235 /// var result = options.Remove(2050);
237 public bool Remove(ushort key)
239 bool isRemoved = _options.Remove(key);
242 int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key);
243 if (ret != (int)IoTConnectivityError.None)
245 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option");
246 throw IoTConnectivityErrorFactory.GetException(ret);
253 /// Gets the value associated with the specified key.
255 /// <param name="key">The option id</param>
256 /// <param name="value">Value corresponding to option id</param>
257 /// <returns>True if the key exists, false otherwise</returns>
259 /// ResourceOptions options = new ResourceOptions();
260 /// options.Add(2050, "12345");
262 /// var isPresent = options.TryGetValue(2050, out value);
264 /// Console.WriteLine("value : {0}", value);
266 public bool TryGetValue(ushort key, out string value)
268 return _options.TryGetValue(key, out value);
272 /// Adds options key and value as a key value pair
274 /// <param name="item">The key value pair</param>
275 /// <seealso cref="Remove()"/>
277 /// ResourceOptions options = new ResourceOptions();
278 /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
280 public void Add(KeyValuePair<ushort, string> item)
282 Add(item.Key, item.Value);
286 /// Clears the Options collection
288 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
289 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
291 /// ResourceOptions options = new ResourceOptions();
292 /// options.Add(2050, "12345");
293 /// options.Add(2055, "sample");
298 foreach (ushort key in Keys)
300 int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key);
301 if (ret != (int)IoTConnectivityError.None)
303 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option");
304 throw IoTConnectivityErrorFactory.GetException(ret);
311 /// Checks if the given option pair exists
313 /// <param name="item">The key value pair</param>
314 /// <returns>True if exists. Otherwise, false</returns>
316 /// ResourceOptions options = new ResourceOptions();
317 /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
318 /// var isPresent = options.Contains(new KeyValuePair<ushort, string>(2050, "12345"));
320 /// Console.WriteLine("Key value pair is present");
322 public bool Contains(KeyValuePair<ushort, string> item)
324 return _options.Contains(item);
328 /// Copies the elements of the options collection to an Array, starting at a particular index.
330 /// <param name="array">The destination array</param>
331 /// <param name="arrayIndex">Index parameter</param>
333 /// ResourceOptions options = new ResourceOptions();
334 /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
335 /// KeyValuePair<ushort, string>[] dest = new KeyValuePair<ushort, string>[options.Count];
336 /// options.CopyTo(dest, 0);
337 /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value);
339 public void CopyTo(KeyValuePair<ushort, string>[] array, int arrayIndex)
341 _options.CopyTo(array, arrayIndex);
345 /// Remove the given key value pair from the options
347 /// <param name="item">The key value pair to remove</param>
348 /// <returns>True if operation is successful. Otherwise, false</returns>
349 /// <seealso cref="Add()"/>
351 /// ResourceOptions options = new ResourceOptions();
352 /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
353 /// var result = options.Remove(new KeyValuePair<ushort, string>(2050, "12345"));
355 public bool Remove(KeyValuePair<ushort, string> item)
357 return Remove(item.Key);
361 /// Get the enumerator to options collection
363 /// <returns>Enumerator to option pairs</returns>
365 /// ResourceOptions options = new ResourceOptions();
366 /// options.Add(new KeyValuePair<ushort, string>(2050, "sample1"));
367 /// options.Add(new KeyValuePair<ushort, string>(2055, "sample2"));
368 /// foreach (KeyValuePair<string, object> pair in options)
370 /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
373 public IEnumerator<KeyValuePair<ushort, string>> GetEnumerator()
375 return _options.GetEnumerator();
379 /// Releases any unmanaged resources used by this object.
381 public void Dispose()
384 GC.SuppressFinalize(this);
388 /// Get the enumerator to options collection
390 /// <returns>Enumerator to option pairs</returns>
392 /// ResourceOptions options = new ResourceOptions();
393 /// options.Add(new KeyValuePair<ushort, string>(2050, "sample1"));
394 /// options.Add(new KeyValuePair<ushort, string>(2055, "sample2"));
395 /// foreach (KeyValuePair<string, object> pair in options)
397 /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
400 IEnumerator IEnumerable.GetEnumerator()
402 return _options.GetEnumerator();
406 /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
408 /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
409 protected virtual void Dispose(bool disposing)
416 // Free managed objects
419 Interop.IoTConnectivity.Common.Options.Destroy(_resourceOptionsHandle);
423 private bool IsValid(ushort key, string value)
425 return (key > IdMin && key < IdMax && value.Length <= DataMax && _options.Count() < MaxSize);