/*
* 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 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 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 query key and value as a key value pair
///
/// 3
/// The key value pair
/// http://tizen.org/feature/iot.ocf
///
///
/// ResourceQuery query = new ResourceQuery();
/// query.Add(new KeyValuePair("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
///
/// ResourceQuery query = new ResourceQuery();
/// query.Add(new KeyValuePair("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
///
/// ResourceQuery query = new ResourceQuery();
/// query.Add(new KeyValuePair("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);
}
///
/// Remove 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
///
/// ResourceQuery query = new ResourceQuery();
/// query.Add(new KeyValuePair("key1", "value1"));
/// var result = query.Remove(new KeyValuePair("key1", "value1"));
///
public bool Remove(KeyValuePair item)
{
return Remove(item.Key);
}
///
/// Get the enumerator to query collection
///
/// 3
/// Enumerator to query pairs
///
/// ResourceQuery query = new ResourceQuery();
/// query.Add(new KeyValuePair("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();
}
///
/// Get the enumerator to query collection
///
/// 3
/// Enumerator to query pairs
///
/// ResourceQuery query = new ResourceQuery();
/// query.Add(new KeyValuePair("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;
}
}
}