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;
21 using System.Runtime.InteropServices;
23 namespace Tizen.Network.IoTConnectivity
26 /// This class provides APIs to manage the query of request.
28 /// <since_tizen> 3 </since_tizen>
29 public class ResourceQuery : IDictionary<string, string>, IDisposable
31 internal const int QueryMaxLenth = 64;
32 internal IntPtr _resourceQueryHandle = IntPtr.Zero;
33 private readonly IDictionary<string, string> _query = new Dictionary<string, string>();
34 private bool _disposed = false;
37 /// The resource query constructor.
39 /// <since_tizen> 3 </since_tizen>
40 /// <feature>http://tizen.org/feature/iot.ocf</feature>
41 /// <seealso cref="Add(string, string)"/>
42 /// <seealso cref="Remove(string)"/>
43 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
44 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory.</exception>
46 /// ResourceQuery query = new ResourceQuery();
48 public ResourceQuery()
50 int ret = Interop.IoTConnectivity.Common.Query.Create(out _resourceQueryHandle);
51 if (ret != (int)IoTConnectivityError.None)
53 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create query");
54 throw IoTConnectivityErrorFactory.GetException(ret);
58 internal ResourceQuery(IntPtr resourceQueryHandleToClone)
60 int ret = Interop.IoTConnectivity.Common.Query.Create(out _resourceQueryHandle);
61 if (ret != (int)IoTConnectivityError.None)
63 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create query");
64 throw IoTConnectivityErrorFactory.GetException(ret);
67 Interop.IoTConnectivity.Common.Query.QueryCallback forEachCallback = (string key, string value, IntPtr userData) =>
73 ret = Interop.IoTConnectivity.Common.Query.Foreach(resourceQueryHandleToClone, forEachCallback, IntPtr.Zero);
74 if (ret != (int)IoTConnectivityError.None)
76 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to iterate query");
77 throw IoTConnectivityErrorFactory.GetException(ret);
82 /// Destructor of the ResourceQuery class.
90 /// Gets and sets the resource type of the query.
92 /// <since_tizen> 3 </since_tizen>
93 /// <value>The resource type of the query.</value>
94 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
95 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
96 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
98 /// ResourceQuery query = new ResourceQuery();
99 /// query.Type = "org.tizen.light";
100 /// Console.WriteLine("Type of query : {0}", query.Type);
107 int ret = Interop.IoTConnectivity.Common.Query.GetResourceType(_resourceQueryHandle, out type);
108 if (ret != (int)IoTConnectivityError.None)
110 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type");
113 return (type != IntPtr.Zero) ? Marshal.PtrToStringAnsi(type) : string.Empty;
117 int ret = (int)IoTConnectivityError.InvalidParameter;
118 if (ResourceTypes.IsValid(value))
119 ret = Interop.IoTConnectivity.Common.Query.SetResourceType(_resourceQueryHandle, value);
121 if (ret != (int)IoTConnectivityError.None)
123 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set type");
124 throw IoTConnectivityErrorFactory.GetException(ret);
130 /// Gets and sets the resource interface of the query.
132 /// <since_tizen> 3 </since_tizen>
134 /// The resource interface of the query.
135 /// Setter value could be a value, such as <see cref="ResourceInterfaces.DefaultInterface"/>.
137 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
138 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
139 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
141 /// ResourceQuery query = new ResourceQuery();
142 /// query.Interface = ResourceInterfaces.LinkInterface;
144 public string Interface
149 int ret = Interop.IoTConnectivity.Common.Query.GetInterface(_resourceQueryHandle, out iface);
150 if (ret != (int)IoTConnectivityError.None)
152 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get interface");
155 return (iface != IntPtr.Zero) ? Marshal.PtrToStringAnsi(iface) : string.Empty;
159 int ret = (int)IoTConnectivityError.InvalidParameter;
160 if (ResourceInterfaces.IsValid(value))
161 ret = Interop.IoTConnectivity.Common.Query.SetInterface(_resourceQueryHandle, value);
163 if (ret != (int)IoTConnectivityError.None)
165 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set interface");
166 throw IoTConnectivityErrorFactory.GetException(ret);
172 /// Contains all the query keys.
174 /// <since_tizen> 3 </since_tizen>
175 /// <value>All the query keys.</value>
177 /// ResourceQuery query = new ResourceQuery();
178 /// query.Add("key", "value");
179 /// query.Add("newKey", "sample value");
180 /// var keys = query.Keys;
181 /// Console.WriteLine("Resource query contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1));
183 public ICollection<string> Keys
192 /// Contains all the query values.
194 /// <since_tizen> 3 </since_tizen>
195 /// <value>All the query values.</value>
197 /// ResourceQuery query = new ResourceQuery();
198 /// query.Add("key", "value");
199 /// query.Add("newKey", "sample value");
200 /// var values = query.Values;
201 /// Console.WriteLine("Resource query contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1));
203 public ICollection<string> Values
207 return _query.Values;
212 /// Gets the number of query elements.
214 /// <since_tizen> 3 </since_tizen>
215 /// <value>The number of query elements.</value>
217 /// ResourceQuery query = new ResourceQuery();
218 /// query.Add("key", "value");
219 /// query.Add("newKey", "sample value");
220 /// var count = query.Count;
221 /// Console.WriteLine("There are {0} keys in the query object", count);
232 /// Represents whether the collection is readonly.
234 /// <since_tizen> 3 </since_tizen>
235 /// <value>Whether the collection is readonly.</value>
237 /// ResourceQuery query = new ResourceQuery();
238 /// if (query.IsReadOnly)
239 /// Console.WriteLine("Read only query");
241 public bool IsReadOnly
245 return _query.IsReadOnly;
250 /// Gets or sets the query data.
252 /// <since_tizen> 3 </since_tizen>
253 /// <value>The query data.</value>
254 /// <param name="key">The query key to get or set.</param>
255 /// <returns>The query with the specified key.</returns>
257 /// ResourceQuery query = new ResourceQuery();
258 /// query["key1"] = "sample-data";
259 /// Console.WriteLine("query has : {0}", query["key1"]);
261 public string this[string key]
275 /// Checks whether the given key exists in the query collection.
277 /// <since_tizen> 3 </since_tizen>
278 /// <param name="key">The key to look for.</param>
279 /// <returns>true if exists. Otherwise, false.</returns>
281 /// ResourceQuery query = new ResourceQuery();
282 /// query.Add("key1", "value1");
283 /// if (query.ContainsKey("key1"))
284 /// Console.WriteLine("query conatins key : key1");
286 public bool ContainsKey(string key)
288 return _query.ContainsKey(key);
292 /// Adds a new key and correspoding value into the query.
294 /// <since_tizen> 3 </since_tizen>
296 /// The full length of query should be less than or equal to 64.
298 /// <param name="key">The key of the query to insert.</param>
299 /// <param name="value">The string data to insert into the query.</param>
300 /// <feature>http://tizen.org/feature/iot.ocf</feature>
301 /// <seealso cref="Remove(string)"/>
302 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
303 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
304 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
306 /// ResourceQuery query = new ResourceQuery();
307 /// query.Add("key1", "value1");
309 public void Add(string key, string value)
311 if (CanAddQuery(key, value))
313 int ret = Interop.IoTConnectivity.Common.Query.Add(_resourceQueryHandle, key, value);
314 if (ret != (int)IoTConnectivityError.None)
316 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add query");
317 throw IoTConnectivityErrorFactory.GetException(ret);
319 _query.Add(key, value);
323 Log.Error(IoTConnectivityErrorFactory.LogTag, "Query cannot be added");
324 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
329 /// Removes the key and its associated value from the query.
331 /// <since_tizen> 3 </since_tizen>
332 /// <param name="key">The ID of the query to delete.</param>
333 /// <returns>True if operation is successful. Otherwise, false.</returns>
334 /// <feature>http://tizen.org/feature/iot.ocf</feature>
335 /// <seealso cref="Add(string, string)"/>
336 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
337 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
338 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
340 /// ResourceQuery query = new ResourceQuery();
341 /// query.Add("key1", "value1");
342 /// var result = query.Remove("key1");
344 public bool Remove(string key)
346 int ret = Interop.IoTConnectivity.Common.Query.Remove(_resourceQueryHandle, key);
347 if (ret != (int)IoTConnectivityError.None)
349 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove query");
350 throw IoTConnectivityErrorFactory.GetException(ret);
353 bool isRemoved = _query.Remove(key);
359 /// Gets the value associated with the specified key.
361 /// <since_tizen> 3 </since_tizen>
362 /// <param name="key">The query key.</param>
363 /// <param name="value">Value corresponding to query key.</param>
364 /// <returns>True if the key exists, false otherwise.</returns>
366 /// ResourceQuery query = new ResourceQuery();
367 /// query.Add("key1", "value1");
369 /// var isPresent = query.TryGetValue("key1", out value);
371 /// Console.WriteLine("value : {0}", value);
373 public bool TryGetValue(string key, out string value)
375 return _query.TryGetValue(key, out value);
379 /// Adds a query key and a value as a key value pair.
381 /// <since_tizen> 3 </since_tizen>
382 /// <param name="item">The key value pair.</param>
383 /// <feature>http://tizen.org/feature/iot.ocf</feature>
384 /// <seealso cref="Remove(KeyValuePair{string, string})"/>
386 /// ResourceQuery query = new ResourceQuery();
387 /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
389 public void Add(KeyValuePair<string, string> item)
391 Add(item.Key, item.Value);
395 /// Clears the query collection.
397 /// <since_tizen> 3 </since_tizen>
398 /// <feature>http://tizen.org/feature/iot.ocf</feature>
399 /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported.</exception>
400 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid.</exception>
402 /// ResourceQuery query = new ResourceQuery();
403 /// query.Add("key1", "value1");
404 /// query.Add("key2", "value2");
409 foreach (string key in _query.Keys)
411 int ret = Interop.IoTConnectivity.Common.Query.Remove(_resourceQueryHandle, key);
412 if (ret != (int)IoTConnectivityError.None)
414 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to clear query");
415 throw IoTConnectivityErrorFactory.GetException(ret);
422 /// Checks if the given query pair exists.
424 /// <since_tizen> 3 </since_tizen>
425 /// <param name="item">The key value pair.</param>
426 /// <returns>True if exists. Otherwise, false.</returns>
428 /// ResourceQuery query = new ResourceQuery();
429 /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
430 /// var isPresent = query.Contains(new KeyValuePair<string, string>("key1", "value1"));
432 /// Console.WriteLine("Key value pair is present");
434 public bool Contains(KeyValuePair<string, string> item)
436 return _query.Contains(item);
440 /// Copies the elements of the query collection to an array, starting at a particular index.
442 /// <since_tizen> 3 </since_tizen>
443 /// <param name="array">The destination array.</param>
444 /// <param name="arrayIndex">Index parameter.</param>
446 /// ResourceQuery query = new ResourceQuery();
447 /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
448 /// KeyValuePair<string, string>[] dest = new KeyValuePair<string, string>[query.Count];
449 /// query.CopyTo(dest, 0);
450 /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value);
452 public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
454 _query.CopyTo(array, arrayIndex);
458 /// Removes the given key value pair from the query.
460 /// <since_tizen> 3 </since_tizen>
461 /// <param name="item">The key value pair to remove.</param>
462 /// <returns>True if operation is successful. Otherwise, false.</returns>
463 /// <feature>http://tizen.org/feature/iot.ocf</feature>
464 /// <seealso cref="Add(KeyValuePair{string, string})"/>
465 /// <exception cref="ArgumentException">Thrown when there is an invalid parameter.</exception>
467 /// ResourceQuery query = new ResourceQuery();
468 /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
469 /// var result = query.Remove(new KeyValuePair<string, string>("key1", "value1"));
471 public bool Remove(KeyValuePair<string, string> item)
473 return Remove(item.Key);
477 /// Gets the enumerator to the query collection.
479 /// <since_tizen> 3 </since_tizen>
480 /// <returns>Enumerator to query pairs.</returns>
482 /// ResourceQuery query = new ResourceQuery();
483 /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
484 /// query.Add(new KeyValuePair<string, string>("key2", "value2"));
485 /// foreach (KeyValuePair<string, string> pair in query)
487 /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
490 public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
492 return _query.GetEnumerator();
496 /// Gets the enumerator to the query collection.
498 /// <since_tizen> 3 </since_tizen>
499 /// <returns>The enumerator to the query pairs.</returns>
501 /// ResourceQuery query = new ResourceQuery();
502 /// query.Add(new KeyValuePair<string, string>("key1", "value1"));
503 /// query.Add(new KeyValuePair<string, string>("key2", "value2"));
504 /// foreach (KeyValuePair<string, string> pair in query)
506 /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value);
509 IEnumerator IEnumerable.GetEnumerator()
511 return _query.GetEnumerator();
515 /// Releases any unmanaged resources used by this object.
517 /// <since_tizen> 3 </since_tizen>
518 /// <feature>http://tizen.org/feature/iot.ocf</feature>
519 public void Dispose()
522 GC.SuppressFinalize(this);
526 /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
528 /// <since_tizen> 3 </since_tizen>
529 /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
530 /// <feature>http://tizen.org/feature/iot.ocf</feature>
531 protected virtual void Dispose(bool disposing)
538 // Free managed objects
541 Interop.IoTConnectivity.Common.Query.Destroy(_resourceQueryHandle);
545 private bool CanAddQuery(string newKey, string newValue)
548 foreach (string key in Keys)
550 queryLenth += key.Length + 2;
552 foreach (string value in Values)
554 queryLenth += value.Length;
557 if ((newKey.Length + newValue.Length + queryLenth + 2) < QueryMaxLenth)