Update content of nuspec file
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.IoTConnectivity / Tizen.Network.IoTConnectivity / ResourceOptions.cs
1  /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 using System;
19 using System.Collections;
20 using System.Collections.Generic;
21 using System.Linq;
22
23 namespace Tizen.Network.IoTConnectivity
24 {
25     /// <summary>
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.
29     /// </summary>
30     public class ResourceOptions : IDictionary<ushort, string>, IDisposable
31     {
32         internal const int MaxSize = 2;
33         internal const int IdMin = 2048;
34         internal const int IdMax = 3000;
35         internal const int DataMax = 15;
36
37         internal IntPtr _resourceOptionsHandle = IntPtr.Zero;
38         private readonly IDictionary<ushort, string> _options = new Dictionary<ushort, string>();
39         private bool _disposed = false;
40
41         /// <summary>
42         /// The resource options constructor
43         /// </summary>
44         /// <seealso cref="Add()"/>
45         /// <seealso cref="Remove()"/>
46         /// <code>
47         /// ResourceOptions options = new ResourceOptions();
48         /// </code>
49         public ResourceOptions()
50         {
51             int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle);
52             if (ret != (int)IoTConnectivityError.None)
53             {
54                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options");
55                 throw IoTConnectivityErrorFactory.GetException(ret);
56             }
57         }
58
59         // internal constructor
60         internal ResourceOptions(IntPtr handleToClone)
61         {
62             int ret = Interop.IoTConnectivity.Common.Options.Create(out _resourceOptionsHandle);
63             if (ret != (int)IoTConnectivityError.None)
64             {
65                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create options");
66                 throw IoTConnectivityErrorFactory.GetException(ret);
67             }
68
69             Interop.IoTConnectivity.Common.Options.OptionsCallback forEachCallback = (ushort id, string value, IntPtr userData) =>
70             {
71                 Add(id, value);
72                 return true;
73             };
74
75             ret = Interop.IoTConnectivity.Common.Options.ForEach(handleToClone, forEachCallback, IntPtr.Zero);
76             if (ret != (int)IoTConnectivityError.None)
77             {
78                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to iterate options");
79                 throw IoTConnectivityErrorFactory.GetException(ret);
80             }
81         }
82
83         /// <summary>
84         /// Destructor of the ResourceOptions class.
85         /// </summary>
86         ~ResourceOptions()
87         {
88             Dispose(false);
89         }
90
91         /// <summary>
92         /// Contains all the Option keys
93         /// </summary>
94         /// <code>
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));
100         /// </code>
101         public ICollection<ushort> Keys
102         {
103             get
104             {
105                 return _options.Keys;
106             }
107         }
108
109         /// <summary>
110         /// Contains all the Option values
111         /// </summary>
112         /// <code>
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));
118         /// </code>
119         public ICollection<string> Values
120         {
121             get
122             {
123                 return _options.Values;
124             }
125         }
126
127         /// <summary>
128         /// Gets the number of options
129         /// </summary>
130         /// <code>
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);
136         /// </code>
137         public int Count
138         {
139             get
140             {
141                 return _options.Count;
142             }
143         }
144
145         /// <summary>
146         /// Represents whether the collection is readonly
147         /// </summary>
148         /// <code>
149         /// ResourceOptions options = new ResourceOptions();
150         /// if (options.IsReadOnly)
151         ///     Console.WriteLine("Read only options");
152         /// </code>
153         public bool IsReadOnly
154         {
155             get
156             {
157                 return _options.IsReadOnly;
158             }
159         }
160
161         /// <summary>
162         /// Gets or sets the option data
163         /// </summary>
164         /// <remarks>
165         /// <param name="key">The option id to get or set.</param>
166         /// <returns>The option with the specified id.</returns>
167         /// <code>
168         /// ResourceOptions options = new ResourceOptions();
169         /// options[2055] = "sample-data";
170         /// Console.WriteLine("Option has : {0}", options[2055]);
171         /// </code>
172         public string this[ushort key]
173         {
174             get
175             {
176                 return _options[key];
177             }
178             set
179             {
180                 Add(key, value);
181             }
182         }
183
184         /// <summary>
185         /// Checks whether the given key exists in Options collection
186         /// </summary>
187         /// <param name="key">The key to look for</param>
188         /// <returns>true if exists. Otherwise, false</returns>
189         /// <code>
190         /// ResourceOptions options = new ResourceOptions();
191         /// options.Add(2050, "sample-data");
192         /// if (options.ContainsKey(2050))
193         ///     Console.WriteLine("options conatins key : 2050");
194         /// </code>
195         public bool ContainsKey(ushort key)
196         {
197             return _options.ContainsKey(key);
198         }
199
200         /// <summary>
201         /// Adds a new id and a correspoding data into the options.
202         /// </summary>
203         /// <remarks>
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.
207         /// </remarks>
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()"/>
211         /// <code>
212         /// ResourceOptions options = new ResourceOptions();
213         /// options.Add(2050, "sample-data");
214         /// </code>
215         public void Add(ushort key, string value)
216         {
217             int ret = (int)IoTConnectivityError.InvalidParameter;
218             if (IsValid(key, value))
219             {
220                 ret = Interop.IoTConnectivity.Common.Options.Add(_resourceOptionsHandle, key, value);
221                 if (ret != (int)IoTConnectivityError.None)
222                 {
223                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add option");
224                     throw IoTConnectivityErrorFactory.GetException(ret);
225                 }
226                 _options.Add(key, value);
227             }
228             else
229             {
230                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid options");
231                 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
232             }
233         }
234
235         /// <summary>
236         /// Removes the id and its associated data from the options.
237         /// </summary>
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()"/>
241         /// <code>
242         /// ResourceOptions options = new ResourceOptions();
243         /// options.Add(2050, "12345");
244         /// var result = options.Remove(2050);
245         /// </code>
246         public bool Remove(ushort key)
247         {
248             bool isRemoved = _options.Remove(key);
249             if (isRemoved)
250             {
251                 int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key);
252                 if (ret != (int)IoTConnectivityError.None)
253                 {
254                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option");
255                     throw IoTConnectivityErrorFactory.GetException(ret);
256                 }
257             }
258             return isRemoved;
259         }
260
261         /// <summary>
262         /// Gets the value associated with the specified key.
263         /// </summary>
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>
267         /// <code>
268         /// ResourceOptions options = new ResourceOptions();
269         /// options.Add(2050, "12345");
270         /// string value;
271         /// var isPresent = options.TryGetValue(2050, out value);
272         /// if (isPresent)
273         ///     Console.WriteLine("value : {0}", value);
274         /// </code>
275         public bool TryGetValue(ushort key, out string value)
276         {
277             return _options.TryGetValue(key, out value);
278         }
279
280         /// <summary>
281         ///  Adds options key and value as a key value pair
282         /// </summary>
283         /// <param name="item">The key value pair</param>
284         /// <seealso cref="Remove()"/>
285         /// <code>
286         /// ResourceOptions options = new ResourceOptions();
287         /// options.Add(new KeyValuePair<ushort, string>(2050, "12345"));
288         /// </code>
289         public void Add(KeyValuePair<ushort, string> item)
290         {
291             Add(item.Key, item.Value);
292         }
293
294         /// <summary>
295         /// Clears the Options collection
296         /// </summary>
297         /// <code>
298         /// ResourceOptions options = new ResourceOptions();
299         /// options.Add(2050, "12345");
300         /// options.Add(2055, "sample");
301         /// options.Clear();
302         /// </code>
303         public void Clear()
304         {
305             foreach (ushort key in Keys)
306             {
307                 int ret = Interop.IoTConnectivity.Common.Options.Remove(_resourceOptionsHandle, key);
308                 if (ret != (int)IoTConnectivityError.None)
309                 {
310                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove option");
311                     throw IoTConnectivityErrorFactory.GetException(ret);
312                 };
313             }
314             _options.Clear();
315         }
316
317         /// <summary>
318         /// Checks if the given option pair exists
319         /// </summary>
320         /// <param name="item">The key value pair</param>
321         /// <returns>True if exists. Otherwise, false</returns>
322         /// <code>
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"));
326         /// if (isPresent)
327         ///     Console.WriteLine("Key value pair is present");
328         /// </code>
329         public bool Contains(KeyValuePair<ushort, string> item)
330         {
331             return _options.Contains(item);
332         }
333
334         /// <summary>
335         /// Copies the elements of the options collection to an Array, starting at a particular index.
336         /// </summary>
337         /// <param name="array">The destination array</param>
338         /// <param name="arrayIndex">Index parameter</param>
339         /// <code>
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);
345         /// </code>
346         public void CopyTo(KeyValuePair<ushort, string>[] array, int arrayIndex)
347         {
348             _options.CopyTo(array, arrayIndex);
349         }
350
351         /// <summary>
352         /// Remove the given key value pair from the options
353         /// </summary>
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()"/>
357         /// <code>
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"));
361         /// </code>
362         public bool Remove(KeyValuePair<ushort, string> item)
363         {
364             return Remove(item.Key);
365         }
366
367         /// <summary>
368         /// Get the enumerator to options collection
369         /// </summary>
370         /// <returns>Enumerator to option pairs</returns>
371         /// <code>
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)
376         /// {
377         ///     Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
378         /// }
379         /// </code>
380         public IEnumerator<KeyValuePair<ushort, string>> GetEnumerator()
381         {
382             return _options.GetEnumerator();
383         }
384
385         /// <summary>
386         /// Releases any unmanaged resources used by this object.
387         /// </summary>
388         public void Dispose()
389         {
390             Dispose(true);
391             GC.SuppressFinalize(this);
392         }
393
394         /// <summary>
395         /// Get the enumerator to options collection
396         /// </summary>
397         /// <returns>Enumerator to option pairs</returns>
398         /// <code>
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)
403         /// {
404         ///     Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
405         /// }
406         /// </code>
407         IEnumerator IEnumerable.GetEnumerator()
408         {
409             return _options.GetEnumerator();
410         }
411
412         /// <summary>
413         /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
414         /// </summary>
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)
417         {
418             if (_disposed)
419                 return;
420
421             if (disposing)
422             {
423                 // Free managed objects
424             }
425
426             Interop.IoTConnectivity.Common.Options.Destroy(_resourceOptionsHandle);
427             _disposed = true;
428         }
429
430         private bool IsValid(ushort key, string value)
431         {
432             return (key > IdMin && key < IdMax && value.Length <= DataMax && _options.Count() < MaxSize);
433         }
434     }
435 }