4 * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 #include "ctsvc_internal.h"
23 #include "ctsvc_filter.h"
25 static inline bool _filter_property_check(const property_info_s *properties,
26 int count, unsigned int property_id, int *type)
29 for (i = 0; i < count; i++) {
30 property_info_s *p = (property_info_s*)&(properties[i]);
31 if (property_id == p->property_id) {
32 if (p->property_type == CTSVC_SEARCH_PROPERTY_ALL
33 || p->property_type == CTSVC_SEARCH_PROPERTY_FILTER) {
34 *type = (property_id & CTSVC_VIEW_DATA_TYPE_MASK);
44 EXPORT_API int contacts_filter_create(const char *view_uri, contacts_filter_h *out_filter)
46 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
47 ctsvc_composite_filter_s *com_filter;
49 RETV_IF(NULL == out_filter, CONTACTS_ERROR_INVALID_PARAMETER);
52 RETV_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER);
54 com_filter = calloc(1, sizeof(ctsvc_composite_filter_s));
55 RETV_IF(NULL == com_filter, CONTACTS_ERROR_OUT_OF_MEMORY);
57 #ifdef _CONTACTS_IPC_CLIENT
58 ctsvc_view_uri_init();
61 com_filter->filter_type = CTSVC_FILTER_COMPOSITE;
62 com_filter->view_uri = strdup(view_uri);
63 com_filter->properties = (property_info_s*)ctsvc_view_get_all_property_infos(view_uri,
64 &com_filter->property_count);
65 *out_filter = (contacts_filter_h)com_filter;
66 return CONTACTS_ERROR_NONE;
69 EXPORT_API int contacts_filter_add_operator(contacts_filter_h filter,
70 contacts_filter_operator_e op)
72 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
73 ctsvc_composite_filter_s *com_filter;
75 RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
77 com_filter = (ctsvc_composite_filter_s*)filter;
78 RETVM_IF(g_slist_length(com_filter->filter_ops) != (g_slist_length(com_filter->filters)-1),
79 CONTACTS_ERROR_INVALID_PARAMETER, "Please check the operator of filter");
81 com_filter->filter_ops = g_slist_append(com_filter->filter_ops, (void*)op);
83 return CONTACTS_ERROR_NONE;
86 EXPORT_API int contacts_filter_add_filter(contacts_filter_h filter1, contacts_filter_h filter2)
88 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
90 ctsvc_composite_filter_s *s_filter1;
91 ctsvc_composite_filter_s *s_filter2;
92 contacts_filter_h new_filter;
94 RETV_IF(NULL == filter1 || NULL == filter2, CONTACTS_ERROR_INVALID_PARAMETER);
95 s_filter1 = (ctsvc_composite_filter_s*)filter1;
96 s_filter2 = (ctsvc_composite_filter_s*)filter2;
98 RETVM_IF(g_slist_length(s_filter1->filter_ops) != (g_slist_length(s_filter1->filters)),
99 CONTACTS_ERROR_INVALID_PARAMETER, "Please check the operator of filter");
100 RETVM_IF(STRING_EQUAL != strcmp(s_filter1->view_uri, s_filter2->view_uri),
101 CONTACTS_ERROR_INVALID_PARAMETER,
102 "The filter view_uri is different (filter1:%s, filter2:%s)",
103 s_filter1->view_uri, s_filter2->view_uri);
105 ret = ctsvc_filter_clone(filter2, &new_filter);
106 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_filter_clone is Fail(%d)", ret);
107 s_filter1->filters = g_slist_append(s_filter1->filters, new_filter);
109 return CONTACTS_ERROR_NONE;
112 static int _filter_create_attribute(ctsvc_composite_filter_s *com_filter,
113 unsigned int property_id,
116 ctsvc_attribute_filter_s **out_filter)
118 ctsvc_attribute_filter_s *filter;
122 RETVM_IF(g_slist_length(com_filter->filter_ops) != g_slist_length(com_filter->filters),
123 CONTACTS_ERROR_INVALID_PARAMETER, "Please check the operator of filter");
125 find = _filter_property_check(com_filter->properties, com_filter->property_count, property_id, &type);
126 RETVM_IF(false == find, CONTACTS_ERROR_INVALID_PARAMETER,
127 "property_id(%d) is not supported on view_uri(%s)", property_id, com_filter->view_uri);
129 if (type == CTSVC_VIEW_DATA_TYPE_INT && CTSVC_FILTER_INT != filter_type) {
130 /* LCOV_EXCL_START */
131 ERR("use contacts_filter_add_int() (%d)", filter_type);
132 return CONTACTS_ERROR_INVALID_PARAMETER;
136 if (type == CTSVC_VIEW_DATA_TYPE_STR && CTSVC_FILTER_STR != filter_type) {
137 /* LCOV_EXCL_START */
138 ERR("use contacts_filter_add_str() (%d)", filter_type);
139 return CONTACTS_ERROR_INVALID_PARAMETER;
143 if (type == CTSVC_VIEW_DATA_TYPE_BOOL && CTSVC_FILTER_BOOL != filter_type) {
144 /* LCOV_EXCL_START */
145 ERR("use contacts_filter_add_bool() (%d)", filter_type);
146 return CONTACTS_ERROR_INVALID_PARAMETER;
150 if (type == CTSVC_VIEW_DATA_TYPE_LLI && CTSVC_FILTER_LLI != filter_type) {
151 /* LCOV_EXCL_START */
152 ERR("use contacts_filter_add_lli() (%d)", filter_type);
153 return CONTACTS_ERROR_INVALID_PARAMETER;
157 if (type == CTSVC_VIEW_DATA_TYPE_DOUBLE && CTSVC_FILTER_DOUBLE != filter_type) {
158 /* LCOV_EXCL_START */
159 ERR("use contacts_filter_add_double() (%d)", filter_type);
160 return CONTACTS_ERROR_INVALID_PARAMETER;
164 filter = calloc(1, sizeof(ctsvc_attribute_filter_s));
165 if (NULL == filter) {
166 /* LCOV_EXCL_START */
167 ERR("calloc() Fail");
168 return CONTACTS_ERROR_OUT_OF_MEMORY;
171 filter->filter_type = filter_type;
172 filter->property_id = property_id;
173 filter->match = match;
175 com_filter->filters = g_slist_append(com_filter->filters, filter);
176 *out_filter = filter;
177 return CONTACTS_ERROR_NONE;
180 EXPORT_API int contacts_filter_add_str(contacts_filter_h filter, unsigned int property_id,
181 contacts_match_str_flag_e match, const char *match_value)
183 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
184 ctsvc_composite_filter_s *com_filter;
185 ctsvc_attribute_filter_s *str_filter;
188 RETV_IF(NULL == filter || NULL == match_value, CONTACTS_ERROR_INVALID_PARAMETER);
190 com_filter = (ctsvc_composite_filter_s*)filter;
191 ret = _filter_create_attribute(com_filter, property_id, match,
192 CTSVC_FILTER_STR, &str_filter);
193 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
194 "The parameter is not proper (view_uri:%s, property_id:0x%x, match:%d)",
195 com_filter->view_uri, property_id, match);
197 str_filter->value.s = SAFE_STRDUP(match_value);
198 return CONTACTS_ERROR_NONE;
201 EXPORT_API int contacts_filter_add_int(contacts_filter_h filter, unsigned int property_id,
202 contacts_match_int_flag_e match, int match_value)
204 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
205 ctsvc_composite_filter_s *com_filter;
206 ctsvc_attribute_filter_s *int_filter;
209 RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
210 RETVM_IF((CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO == property_id
211 || CTSVC_PROPERTY_PHONELOG_STAT_SIM_SLOT_NO == property_id)
212 && (CONTACTS_MATCH_GREATER_THAN <= match
213 && match <= CONTACTS_MATCH_LESS_THAN_OR_EQUAL),
214 CONTACTS_ERROR_INVALID_PARAMETER, "Not support this condition");
216 com_filter = (ctsvc_composite_filter_s*)filter;
217 ret = _filter_create_attribute(com_filter, property_id, match,
218 CTSVC_FILTER_INT, &int_filter);
219 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
220 "The parameter is not proper (view_uri:%s, property_id:0x%x, match:%d)",
221 com_filter->view_uri, property_id, match);
223 int_filter->value.i = match_value;
225 return CONTACTS_ERROR_NONE;
228 EXPORT_API int contacts_filter_add_lli(contacts_filter_h filter, unsigned int property_id,
229 contacts_match_int_flag_e match, long long int match_value)
231 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
232 ctsvc_composite_filter_s *com_filter;
233 ctsvc_attribute_filter_s *lli_filter;
236 RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
238 com_filter = (ctsvc_composite_filter_s*)filter;
239 ret = _filter_create_attribute(com_filter, property_id, match,
240 CTSVC_FILTER_LLI, &lli_filter);
241 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
242 "The parameter is not proper (view_uri:, property_id:0x%x, match:%d)",
245 lli_filter->value.l = match_value;
247 return CONTACTS_ERROR_NONE;
250 EXPORT_API int contacts_filter_add_double(contacts_filter_h filter, unsigned int property_id,
251 contacts_match_int_flag_e match, double match_value)
253 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
254 ctsvc_composite_filter_s *com_filter;
255 ctsvc_attribute_filter_s *double_filter;
258 RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
260 com_filter = (ctsvc_composite_filter_s*)filter;
261 ret = _filter_create_attribute(com_filter, property_id, match,
262 CTSVC_FILTER_DOUBLE, &double_filter);
263 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
264 "The parameter is not proper (view_uri:, property_id:0x%x, match:%d)",
267 double_filter->value.d = match_value;
269 return CONTACTS_ERROR_NONE;
272 EXPORT_API int contacts_filter_add_bool(contacts_filter_h filter, unsigned int property_id,
275 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
276 ctsvc_composite_filter_s *com_filter;
277 ctsvc_attribute_filter_s *bool_filter;
280 RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
282 com_filter = (ctsvc_composite_filter_s*)filter;
283 ret = _filter_create_attribute(com_filter, property_id, 0, CTSVC_FILTER_BOOL,
285 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
286 "The parameter is not proper (view_uri:, property_id:%d)",
289 bool_filter->value.b = match_value;
291 return CONTACTS_ERROR_NONE;
294 static int __ctsvc_composite_filter_destroy(ctsvc_composite_filter_s *com_filter)
299 RETV_IF(NULL == com_filter, CONTACTS_ERROR_INVALID_PARAMETER);
301 for (cursor = com_filter->filters; cursor; cursor = cursor->next) {
302 ctsvc_filter_s *sub_filter = cursor->data;
304 if (sub_filter->filter_type == CTSVC_FILTER_COMPOSITE) {
305 __ctsvc_composite_filter_destroy((ctsvc_composite_filter_s*)sub_filter);
307 ctsvc_attribute_filter_s *attr = (ctsvc_attribute_filter_s*)sub_filter;
308 if (attr->filter_type == CTSVC_FILTER_STR)
313 g_slist_free(com_filter->filters);
314 g_slist_free(com_filter->filter_ops);
316 free(com_filter->view_uri);
319 return CONTACTS_ERROR_NONE;
323 EXPORT_API int contacts_filter_destroy(contacts_filter_h filter)
325 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
326 RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
327 #ifdef _CONTACTS_IPC_CLIENT
328 ctsvc_view_uri_deinit();
330 return __ctsvc_composite_filter_destroy((ctsvc_composite_filter_s*)filter);
333 static int __ctsvc_attribute_filter_clone(ctsvc_attribute_filter_s *src,
334 ctsvc_attribute_filter_s **dest)
336 ctsvc_attribute_filter_s *out;
337 out = calloc(1, sizeof(ctsvc_attribute_filter_s));
339 /* LCOV_EXCL_START */
340 ERR("calloc() Fail");
341 return CONTACTS_ERROR_OUT_OF_MEMORY;
344 out->filter_type = src->filter_type;
345 out->property_id = src->property_id;
346 out->match = src->match;
347 if (src->filter_type == CTSVC_FILTER_STR)
348 out->value.s = SAFE_STRDUP(src->value.s);
349 else if (src->filter_type == CTSVC_FILTER_INT)
350 out->value.i = src->value.i;
351 else if (src->filter_type == CTSVC_FILTER_BOOL)
352 out->value.b = src->value.b;
353 else if (src->filter_type == CTSVC_FILTER_LLI)
354 out->value.l = src->value.l;
355 else if (src->filter_type == CTSVC_FILTER_DOUBLE)
356 out->value.d = src->value.d;
358 ERR("unknown type (%d)", src->filter_type);
361 return CONTACTS_ERROR_NONE;
364 static int __ctsvc_composite_filter_clone(ctsvc_composite_filter_s * filter,
365 ctsvc_composite_filter_s **out_filter)
368 ctsvc_composite_filter_s *out;
370 RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
371 contacts_filter_create(filter->view_uri, (contacts_filter_h*)&out);
373 for (cursor = filter->filters; cursor; cursor = cursor->next) {
374 ctsvc_filter_s *src = cursor->data;
375 ctsvc_filter_s *dest = NULL;
377 if (src->filter_type == CTSVC_FILTER_COMPOSITE) {
378 __ctsvc_composite_filter_clone((ctsvc_composite_filter_s*)src,
379 (ctsvc_composite_filter_s **)&dest);
381 __ctsvc_attribute_filter_clone((ctsvc_attribute_filter_s*)src,
382 (ctsvc_attribute_filter_s **)&dest);
385 out->filters = g_slist_append(out->filters, dest);
388 out->filter_ops = g_slist_copy(filter->filter_ops);
391 return CONTACTS_ERROR_NONE;
394 int ctsvc_filter_clone(contacts_filter_h filter, contacts_filter_h *out_filter)
396 RETV_IF(NULL == filter || NULL == out_filter, CONTACTS_ERROR_INVALID_PARAMETER);
398 return __ctsvc_composite_filter_clone((ctsvc_composite_filter_s*)filter,
399 (ctsvc_composite_filter_s **)out_filter);