/* * 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.Runtime.InteropServices; namespace Tizen.Network.IoTConnectivity { /// /// This class provides APIs to manage the query of request. /// /// 3 public class ResourceQuery : IDictionary, IDisposable { internal const int QueryMaxLenth = 64; internal IntPtr _resourceQueryHandle = IntPtr.Zero; private readonly IDictionary _query = new Dictionary(); private bool _disposed = false; /// /// The resource query constructor. /// /// 3 /// http://tizen.org/feature/iot.ocf /// /// /// Thrown when the iotcon is not supported. /// Thrown when there is not enough memory. /// /// ResourceQuery query = new ResourceQuery(); /// public ResourceQuery() { int ret = Interop.IoTConnectivity.Common.Query.Create(out _resourceQueryHandle); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create query"); throw IoTConnectivityErrorFactory.GetException(ret); } } internal ResourceQuery(IntPtr resourceQueryHandleToClone) { int ret = Interop.IoTConnectivity.Common.Query.Create(out _resourceQueryHandle); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create query"); throw IoTConnectivityErrorFactory.GetException(ret); } Interop.IoTConnectivity.Common.Query.QueryCallback forEachCallback = (string key, string value, IntPtr userData) => { Add(key, value); return true; }; ret = Interop.IoTConnectivity.Common.Query.Foreach(resourceQueryHandleToClone, forEachCallback, IntPtr.Zero); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to iterate query"); throw IoTConnectivityErrorFactory.GetException(ret); } } /// /// Destructor of the ResourceQuery class. /// ~ResourceQuery() { Dispose(false); } /// /// Gets and sets the resource type of the query. /// /// 3 /// The resource type of the query. /// Thrown when the iotcon is not supported. /// Thrown when there is an invalid parameter. /// Thrown when the operation is invalid. /// /// ResourceQuery query = new ResourceQuery(); /// query.Type = "org.tizen.light"; /// Console.WriteLine("Type of query : {0}", query.Type); /// public string Type { get { IntPtr type; int ret = Interop.IoTConnectivity.Common.Query.GetResourceType(_resourceQueryHandle, out type); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get type"); return ""; } return (type != IntPtr.Zero) ? Marshal.PtrToStringAnsi(type) : string.Empty; } set { int ret = (int)IoTConnectivityError.InvalidParameter; if (ResourceTypes.IsValid(value)) ret = Interop.IoTConnectivity.Common.Query.SetResourceType(_resourceQueryHandle, value); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set type"); throw IoTConnectivityErrorFactory.GetException(ret); } } } /// /// Gets and sets the resource interface of the query. /// /// 3 /// /// The resource interface of the query. /// Setter value could be a value, such as . /// /// Thrown when the iotcon is not supported. /// Thrown when there is an invalid parameter. /// Thrown when the operation is invalid. /// /// ResourceQuery query = new ResourceQuery(); /// query.Interface = ResourceInterfaces.LinkInterface; /// public string Interface { get { IntPtr iface; int ret = Interop.IoTConnectivity.Common.Query.GetInterface(_resourceQueryHandle, out iface); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to get interface"); return ""; } return (iface != IntPtr.Zero) ? Marshal.PtrToStringAnsi(iface) : string.Empty; } set { int ret = (int)IoTConnectivityError.InvalidParameter; if (ResourceInterfaces.IsValid(value)) ret = Interop.IoTConnectivity.Common.Query.SetInterface(_resourceQueryHandle, value); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to set interface"); throw IoTConnectivityErrorFactory.GetException(ret); } } } /// /// Contains all the query keys. /// /// 3 /// All the query keys. /// /// ResourceQuery query = new ResourceQuery(); /// query.Add("key", "value"); /// query.Add("newKey", "sample value"); /// var keys = query.Keys; /// Console.WriteLine("Resource query contains keys {0} and {1}", keys.ElementAt(0), keys.ElementAt(1)); /// public ICollection Keys { get { return _query.Keys; } } /// /// Contains all the query values. /// /// 3 /// All the query values. /// /// ResourceQuery query = new ResourceQuery(); /// query.Add("key", "value"); /// query.Add("newKey", "sample value"); /// var values = query.Values; /// Console.WriteLine("Resource query contains values {0} and {1}", values.ElementAt(0), values.ElementAt(1)); /// public ICollection Values { get { return _query.Values; } } /// /// Gets the number of query elements. /// /// 3 /// The number of query elements. /// /// ResourceQuery query = new ResourceQuery(); /// query.Add("key", "value"); /// query.Add("newKey", "sample value"); /// var count = query.Count; /// Console.WriteLine("There are {0} keys in the query object", count); /// public int Count { get { return _query.Count; } } /// /// Represents whether the collection is readonly. /// /// 3 /// Whether the collection is readonly. /// /// ResourceQuery query = new ResourceQuery(); /// if (query.IsReadOnly) /// Console.WriteLine("Read only query"); /// public bool IsReadOnly { get { return _query.IsReadOnly; } } /// /// Gets or sets the query data. /// /// 3 /// The query data. /// The query key to get or set. /// The query with the specified key. /// /// ResourceQuery query = new ResourceQuery(); /// query["key1"] = "sample-data"; /// Console.WriteLine("query has : {0}", query["key1"]); /// public string this[string key] { get { return _query[key]; } set { Add(key, value); } } /// /// Checks whether the given key exists in the query collection. /// /// 3 /// The key to look for. /// true if exists. Otherwise, false. /// /// ResourceQuery query = new ResourceQuery(); /// query.Add("key1", "value1"); /// if (query.ContainsKey("key1")) /// Console.WriteLine("query conatins key : key1"); /// public bool ContainsKey(string key) { return _query.ContainsKey(key); } /// /// Adds a new key and correspoding value into the query. /// /// 3 /// /// The full length of query should be less than or equal to 64. /// /// The key of the query to insert. /// The string data to insert into the query. /// http://tizen.org/feature/iot.ocf /// /// Thrown when the iotcon is not supported. /// Thrown when there is an invalid parameter. /// Thrown when the operation is invalid. /// /// ResourceQuery query = new ResourceQuery(); /// query.Add("key1", "value1"); /// public void Add(string key, string value) { if (CanAddQuery(key, value)) { int ret = Interop.IoTConnectivity.Common.Query.Add(_resourceQueryHandle, key, value); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add query"); throw IoTConnectivityErrorFactory.GetException(ret); } _query.Add(key, value); } else { Log.Error(IoTConnectivityErrorFactory.LogTag, "Query cannot be added"); throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter); } } /// /// Removes the key and its associated value from the query. /// /// 3 /// The ID of the query 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. /// Thrown when the operation is invalid. /// /// ResourceQuery query = new ResourceQuery(); /// query.Add("key1", "value1"); /// var result = query.Remove("key1"); /// public bool Remove(string key) { int ret = Interop.IoTConnectivity.Common.Query.Remove(_resourceQueryHandle, key); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove query"); throw IoTConnectivityErrorFactory.GetException(ret); } bool isRemoved = _query.Remove(key); return isRemoved; } /// /// Gets the value associated with the specified key. /// /// 3 /// The query key. /// Value corresponding to query key. /// True if the key exists, false otherwise. /// /// ResourceQuery query = new ResourceQuery(); /// query.Add("key1", "value1"); /// string value; /// var isPresent = query.TryGetValue("key1", out value); /// if (isPresent) /// Console.WriteLine("value : {0}", value); /// public bool TryGetValue(string key, out string value) { return _query.TryGetValue(key, out value); } /// /// Adds a query key and a value as a key value pair. /// /// 3 /// The key value pair. /// http://tizen.org/feature/iot.ocf /// /// ("key1", "value1")); /// ]]> public void Add(KeyValuePair item) { Add(item.Key, item.Value); } /// /// Clears the query collection. /// /// 3 /// http://tizen.org/feature/iot.ocf /// Thrown when the iotcon is not supported. /// Thrown when the operation is invalid. /// /// ResourceQuery query = new ResourceQuery(); /// query.Add("key1", "value1"); /// query.Add("key2", "value2"); /// query.Clear(); /// public void Clear() { foreach (string key in _query.Keys) { int ret = Interop.IoTConnectivity.Common.Query.Remove(_resourceQueryHandle, key); if (ret != (int)IoTConnectivityError.None) { Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to clear query"); throw IoTConnectivityErrorFactory.GetException(ret); } } _query.Clear(); } /// /// Checks if the given query pair exists. /// /// 3 /// The key value pair. /// True if exists. Otherwise, false. /// ("key1", "value1")); /// var isPresent = query.Contains(new KeyValuePair("key1", "value1")); /// if (isPresent) /// Console.WriteLine("Key value pair is present"); /// ]]> public bool Contains(KeyValuePair item) { return _query.Contains(item); } /// /// Copies the elements of the query collection to an array, starting at a particular index. /// /// 3 /// The destination array. /// Index parameter. /// ("key1", "value1")); /// KeyValuePair[] dest = new KeyValuePair[query.Count]; /// query.CopyTo(dest, 0); /// Console.WriteLine("Dest conatins ({0}, {1})", dest[0].Key, dest[0].Value); /// ]]> public void CopyTo(KeyValuePair[] array, int arrayIndex) { _query.CopyTo(array, arrayIndex); } /// /// Removes the given key value pair from the query. /// /// 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. /// ("key1", "value1")); /// var result = query.Remove(new KeyValuePair("key1", "value1")); /// ]]> public bool Remove(KeyValuePair item) { return Remove(item.Key); } /// /// Gets the enumerator to the query collection. /// /// 3 /// Enumerator to query pairs. /// ("key1", "value1")); /// query.Add(new KeyValuePair("key2", "value2")); /// foreach (KeyValuePair pair in query) /// { /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value); /// } /// ]]> public IEnumerator> GetEnumerator() { return _query.GetEnumerator(); } /// /// Gets the enumerator to the query collection. /// /// 3 /// The enumerator to the query pairs. /// ("key1", "value1")); /// query.Add(new KeyValuePair("key2", "value2")); /// foreach (KeyValuePair pair in query) /// { /// Console.WriteLine("key : {0}, value : {1}", pair.Key, pair.Value); /// } /// ]]> IEnumerator IEnumerable.GetEnumerator() { return _query.GetEnumerator(); } /// /// Releases any unmanaged resources used by this object. /// /// 3 /// http://tizen.org/feature/iot.ocf public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// 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.Query.Destroy(_resourceQueryHandle); _disposed = true; } private bool CanAddQuery(string newKey, string newValue) { int queryLenth = 0; foreach (string key in Keys) { queryLenth += key.Length + 2; } foreach (string value in Values) { queryLenth += value.Length; } if ((newKey.Length + newValue.Length + queryLenth + 2) < QueryMaxLenth) return true; return false; } } }