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()"/>
47 /// ResourceOptions options = new ResourceOptions();
49 public ResourceOptions()
51 int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle);
52 if (ret != (int)IoTConnectivityError.None)
54 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options");
55 throw IoTConnectivityErrorFactory.GetException(ret);
59 // internal constructor
60 internal ResourceOptions(IntPtr handleToClone)
62 int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle);
63 if (ret != (int)IoTConnectivityError.None)
65 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options");
66 throw IoTConnectivityErrorFactory.GetException(ret);
69 Interop.IoTConnectivity.Common.Options.OptionsCallback forEachCallback = (ushort id, string value, IntPtr userData) =>
75 ret = Interop.IoTConnectivity.Common.Options.ForEach(handleToClone, forEachCallback, IntPtr.Zero);
76 if (ret != (int)IoTConnectivityError.None)
78 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to iterate options");
79 throw IoTConnectivityErrorFactory.GetException(ret);
84 /// Destructor of the ResourceOptions class.
92 /// Contains all the Option keys
95 /// ResourceOptions options = new ResourceOptions();
96 /// options.Add(2050, "sample-data");
97 /// options.Add(2055, "sample value");
98 /// var keys = options.Keys;
99 /// Console.WriteLine("Resource options contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1));
101 public ICollection<ushort> Keys
105 return _options.Keys;
110 /// Contains all the Option values
113 /// ResourceOptions options = new ResourceOptions();
114 /// options.Add(2050, "sample-data");
115 /// options.Add(2055, "sample value");
116 /// var values = options.Values;
117 /// Console.WriteLine("Resource options contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1));
119 public ICollection<string> Values
123 return _options.Values;
128 /// Gets the number of options
131 /// ResourceOptions options = new ResourceOptions();
132 /// options.Add(2050, "sample-data");
133 /// options.Add(2055, "sample value");
134 /// var count = options.Count;
135 /// Console.WriteLine("There are {0} keys in the options object", count);
141 return _options.Count;
146 /// Represents whether the collection is readonly
149 /// ResourceOptions options = new ResourceOptions();
150 /// if (options.IsReadOnly)
151 /// Console.WriteLine("Read only options");
153 public bool IsReadOnly
157 return _options.IsReadOnly;
162 /// Gets or sets the option data
165 /// <param name="key">The option id to get or set.</param>
166 /// <returns>The option with the specified id.</returns>
168 /// ResourceOptions options = new ResourceOptions();
169 /// options[2055] = "sample-data";
170 /// Console.WriteLine("Option has : {0}", options[2055]);
172 public string this[ushort key]
176 return _options[key];
185 /// Checks whether the given key exists in Options collection
187 /// <param name="key">The key to look for</param>
188 /// <returns>true if exists. Otherwise, false</returns>
190 /// ResourceOptions options = new ResourceOptions();
191 /// options.Add(2050, "sample-data");
192 /// if (options.ContainsKey(2050))
193 /// Console.WriteLine("options conatins key : 2050");
195 public bool ContainsKey(ushort key)
197 return _options.ContainsKey(key);
201 /// Adds a new id and a correspoding data into the options.
204 /// ResourceOptions can have up to 2 options. \n
205 /// key is always situated between 2048 and 3000. \n
206 /// Length of option data is less than or equal to 15.
208 /// <param name="key">The id of the option to insert</param>
209 /// <param name="value">The string data to insert into the options</param>
210 /// <seealso cref="Remove()"/>
212 /// ResourceOptions options = new ResourceOptions();
213 /// options.Add(2050, "sample-data");
215 public void Add(ushort key, string value)
217 int ret = (int)IoTConnectivityError.InvalidParameter;
218 if (IsValid(key, value))
220 ret = Interop.IoTConnectivity.Common.Options.Add(_resourceOptionsHandle, key, value);
221 if (ret != (int)IoTConnectivityError.None)
223 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add option");
224 throw IoTConnectivityErrorFactory.GetException(ret);
226 _options.Add(key, value);
230 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid options");
231 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
236 /// Removes the id and its associated data from the options.
238 /// <param name="key">The id of the option to delete</param>
239 /// <returns>True if operation is successful. Otherwise, false</returns>
240 /// <seealso cref="Add()"/>
242 /// ResourceOptions options = new ResourceOptions();
243 /// options.Add(2050, "12345");
244 /// var result = options.Remove(2050);
246 public bool Remove(ushort key)
248 bool isRemoved = _options.Remove(key);
251 int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key);
252 if (ret != (int)IoTConnectivityError.None)
254 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option");
255 throw IoTConnectivityErrorFactory.GetException(ret);
262 /// Gets the value associated with the specified key.
264 /// <param name="key">The option id</param>
265 /// <param name="value">Value corresponding to option id</param>
266 /// <returns>True if the key exists, false otherwise</returns>
268 /// ResourceOptions options = new ResourceOptions();
269 /// options.Add(2050, "12345");
271 /// var isPresent = options.TryGetValue(2050, out value);
273 /// Console.WriteLine("value : {0}", value);
275 public bool TryGetValue(ushort key, out string value)
277 return _options.TryGetValue(key, out value);
281 /// Adds options key and value as a key value pair
283 /// <param name="item">The key value pair</param>
284 /// <seealso cref="Remove()"/>
286 /// ResourceOptions options = new ResourceOptions();
287 /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
289 public void Add(KeyValuePair<ushort, string> item)
291 Add(item.Key, item.Value);
295 /// Clears the Options collection
298 /// ResourceOptions options = new ResourceOptions();
299 /// options.Add(2050, "12345");
300 /// options.Add(2055, "sample");
305 foreach (ushort key in Keys)
307 int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key);
308 if (ret != (int)IoTConnectivityError.None)
310 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option");
311 throw IoTConnectivityErrorFactory.GetException(ret);
318 /// Checks if the given option pair exists
320 /// <param name="item">The key value pair</param>
321 /// <returns>True if exists. Otherwise, false</returns>
323 /// ResourceOptions options = new ResourceOptions();
324 /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
325 /// var isPresent = options.Contains(new KeyValuePair<ushort, string>(2050, "12345"));
327 /// Console.WriteLine("Key value pair is present");
329 public bool Contains(KeyValuePair<ushort, string> item)
331 return _options.Contains(item);
335 /// Copies the elements of the options collection to an Array, starting at a particular index.
337 /// <param name="array">The destination array</param>
338 /// <param name="arrayIndex">Index parameter</param>
340 /// ResourceOptions options = new ResourceOptions();
341 /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
342 /// KeyValuePair<ushort, string>[] dest = new KeyValuePair<ushort, string>[options.Count];
343 /// options.CopyTo(dest, 0);
344 /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value);
346 public void CopyTo(KeyValuePair<ushort, string>[] array, int arrayIndex)
348 _options.CopyTo(array, arrayIndex);
352 /// Remove the given key value pair from the options
354 /// <param name="item">The key value pair to remove</param>
355 /// <returns>True if operation is successful. Otherwise, false</returns>
356 /// <seealso cref="Add()"/>
358 /// ResourceOptions options = new ResourceOptions();
359 /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
360 /// var result = options.Remove(new KeyValuePair<ushort, string>(2050, "12345"));
362 public bool Remove(KeyValuePair<ushort, string> item)
364 return Remove(item.Key);
368 /// Get the enumerator to options collection
370 /// <returns>Enumerator to option pairs</returns>
372 /// ResourceOptions options = new ResourceOptions();
373 /// options.Add(new KeyValuePair<ushort, string>(2050, "sample1"));
374 /// options.Add(new KeyValuePair<ushort, string>(2055, "sample2"));
375 /// foreach (KeyValuePair<string, object> pair in options)
377 /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
380 public IEnumerator<KeyValuePair<ushort, string>> GetEnumerator()
382 return _options.GetEnumerator();
386 /// Releases any unmanaged resources used by this object.
388 public void Dispose()
391 GC.SuppressFinalize(this);
395 /// Get the enumerator to options collection
397 /// <returns>Enumerator to option pairs</returns>
399 /// ResourceOptions options = new ResourceOptions();
400 /// options.Add(new KeyValuePair<ushort, string>(2050, "sample1"));
401 /// options.Add(new KeyValuePair<ushort, string>(2055, "sample2"));
402 /// foreach (KeyValuePair<string, object> pair in options)
404 /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
407 IEnumerator IEnumerable.GetEnumerator()
409 return _options.GetEnumerator();
413 /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
415 /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
416 protected virtual void Dispose(bool disposing)
423 // Free managed objects
426 Interop.IoTConnectivity.Common.Options.Destroy(_resourceOptionsHandle);
430 private bool IsValid(ushort key, string value)
432 return (key > IdMin && key < IdMax && value.Length <= DataMax && _options.Count() < MaxSize);