remove uncovered code
[platform/core/pim/contacts-service.git] / common / ctsvc_record_result.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19 #include "contacts.h"
20
21 #include "ctsvc_internal.h"
22 #include "ctsvc_record.h"
23 #include "ctsvc_view.h"
24 #include "ctsvc_notify.h"
25
26 #ifdef _CONTACTS_IPC_SERVER
27 #include "ctsvc_server_sim.h"
28 #endif /* _CONTACTS_IPC_SERVER */
29
30 static int __ctsvc_result_create(contacts_record_h *out_record);
31 static int __ctsvc_result_destroy(contacts_record_h record, bool delete_child);
32 static int __ctsvc_result_clone(contacts_record_h record, contacts_record_h *out_record);
33 static int __ctsvc_result_get_str_p(contacts_record_h record, unsigned int property_id, char **out_str);
34 static int __ctsvc_result_get_str(contacts_record_h record, unsigned int property_id, char **out_str);
35 static int __ctsvc_result_get_int(contacts_record_h record, unsigned int property_id, int *out_value);
36 static int __ctsvc_result_get_bool(contacts_record_h record, unsigned int property_id, bool *out_value);
37 static int __ctsvc_result_set_int(contacts_record_h record, unsigned int property_id, int value, bool *is_dirty);
38 static int __ctsvc_result_set_bool(contacts_record_h record, unsigned int property_id, bool value, bool *is_dirty);
39 static int __ctsvc_result_set_str(contacts_record_h record, unsigned int property_id, const char *str, bool *is_dirty);
40
41 ctsvc_record_plugin_cb_s result_plugin_cbs = {
42         .create = __ctsvc_result_create,
43         .destroy = __ctsvc_result_destroy,
44         .clone = __ctsvc_result_clone,
45         .get_str = __ctsvc_result_get_str,
46         .get_str_p = __ctsvc_result_get_str_p,
47         .get_int = __ctsvc_result_get_int,
48         .get_bool = __ctsvc_result_get_bool,
49         .get_lli = NULL,
50         .get_double = NULL,
51         .set_str = __ctsvc_result_set_str,
52         .set_int = __ctsvc_result_set_int,
53         .set_bool = __ctsvc_result_set_bool,
54         .set_lli = NULL,
55         .set_double = NULL,
56         .add_child_record = NULL,
57         .remove_child_record = NULL,
58         .get_child_record_count = NULL,
59         .get_child_record_at_p = NULL,
60         .clone_child_record_list = NULL,
61 };
62
63 static int __ctsvc_result_create(contacts_record_h *out_record)
64 {
65         ctsvc_result_s *result;
66         result = calloc(1, sizeof(ctsvc_result_s));
67         RETVM_IF(NULL == result, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() Fail");
68
69         *out_record = (contacts_record_h)result;
70         return CONTACTS_ERROR_NONE;
71 }
72
73 static int __ctsvc_result_destroy(contacts_record_h record, bool delete_child)
74 {
75         GSList *cursor;
76         ctsvc_result_s *result = (ctsvc_result_s*)record;
77
78         for (cursor = result->values; cursor; cursor = cursor->next) {
79                 ctsvc_result_value_s *data = cursor->data;
80                 if (data->type == CTSVC_VIEW_DATA_TYPE_STR)
81                         /* LCOV_EXCL_START */
82                         free(data->value.s);
83                         /* LCOV_EXCL_STOP */
84                 free(data);
85         }
86         g_slist_free(result->values);
87         result->base.plugin_cbs = NULL; /* help to find double destroy bug (refer to the contacts_record_destroy) */
88         free(result->base.properties_flags);
89
90         free(result);
91
92         return CONTACTS_ERROR_NONE;
93 }
94
95 static int __ctsvc_result_clone(contacts_record_h record, contacts_record_h *out_record)
96 {
97         ctsvc_result_s *out_data = NULL;
98         ctsvc_result_s *src_data = NULL;
99         GSList *cursor;
100
101         src_data = (ctsvc_result_s*)record;
102         out_data = calloc(1, sizeof(ctsvc_result_s));
103         RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
104                         "Out of memeory : calloc(ctsvc_result_s) Fail(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
105
106         for (cursor = src_data->values; cursor; cursor = cursor->next) {
107                 ctsvc_result_value_s *src = cursor->data;
108                 ctsvc_result_value_s *dest = calloc(1, sizeof(ctsvc_result_value_s));
109                 if (NULL == dest) {
110                         /* LCOV_EXCL_START */
111                         ERR("calloc() Fail");
112                         __ctsvc_result_destroy((contacts_record_h)out_data, true);
113                         return CONTACTS_ERROR_OUT_OF_MEMORY;
114                         /* LCOV_EXCL_STOP */
115                 }
116
117 /* LCOV_EXCL_START */
118                 dest->property_id = src->property_id;
119                 dest->type = src->type;
120                 switch (src->type) {
121                 case CTSVC_VIEW_DATA_TYPE_BOOL:
122                         dest->value.b = src->value.b;
123                         break;
124                 case CTSVC_VIEW_DATA_TYPE_INT:
125                         dest->value.i = src->value.i;
126                         break;
127                 case CTSVC_VIEW_DATA_TYPE_LLI:
128                         dest->value.l = src->value.l;
129                         break;
130                 case CTSVC_VIEW_DATA_TYPE_STR:
131                         dest->value.s = SAFE_STRDUP(src->value.s);
132                         break;
133                 case CTSVC_VIEW_DATA_TYPE_DOUBLE:
134                         dest->value.d = src->value.d;
135                         break;
136                 default:
137                         break;
138                 }
139                 out_data->values = g_slist_append(out_data->values, (void*)dest);
140         }
141 /* LCOV_EXCL_STOP */
142
143         int ret = ctsvc_record_copy_base(&(out_data->base), &(src_data->base));
144         if (CONTACTS_ERROR_NONE != ret) {
145                 /* LCOV_EXCL_START */
146                 ERR("ctsvc_record_copy_base() Fail");
147                 __ctsvc_result_destroy((contacts_record_h)out_data, true);
148                 return ret;
149                 /* LCOV_EXCL_STOP */
150         }
151
152         *out_record = (contacts_record_h)out_data;
153
154         return CONTACTS_ERROR_NONE;
155 }
156
157 /* LCOV_EXCL_START */
158 static int __ctsvc_result_get_str_real(contacts_record_h record, unsigned int property_id,
159                 char **out_str, bool copy)
160 {
161         ctsvc_result_s *result = (ctsvc_result_s*)record;
162
163         GSList *cursor;
164
165         if (CTSVC_VIEW_DATA_TYPE_STR != (CTSVC_VIEW_DATA_TYPE_STR & property_id)) {
166                 ERR("property_id is not str type.");
167                 return CONTACTS_ERROR_INVALID_PARAMETER;
168         }
169
170         for (cursor = result->values; cursor; cursor = cursor->next) {
171                 ctsvc_result_value_s *data = cursor->data;
172                 if (data->property_id == property_id) {
173                         *out_str = GET_STR(copy, data->value.s);
174                         return CONTACTS_ERROR_NONE;
175                 }
176         }
177
178         return CONTACTS_ERROR_NO_DATA;
179 }
180
181 static int __ctsvc_result_get_str_p(contacts_record_h record, unsigned int property_id, char **out_str)
182 {
183         return __ctsvc_result_get_str_real(record, property_id, out_str, false);
184 }
185
186 static int __ctsvc_result_get_str(contacts_record_h record, unsigned int property_id, char **out_str)
187 {
188         return __ctsvc_result_get_str_real(record, property_id, out_str, true);
189 }
190
191 static int __ctsvc_result_get_int(contacts_record_h record, unsigned int property_id, int *out_value)
192 {
193         ctsvc_result_s *result = (ctsvc_result_s*)record;
194
195         GSList *cursor;
196
197         if (CTSVC_VIEW_DATA_TYPE_INT != (CTSVC_VIEW_DATA_TYPE_INT & property_id)) {
198                 ERR("property_id is not int type.");
199                 return CONTACTS_ERROR_INVALID_PARAMETER;
200         }
201
202         for (cursor = result->values; cursor; cursor = cursor->next) {
203                 ctsvc_result_value_s *data = cursor->data;
204                 if (data->property_id == property_id) {
205                         *out_value = data->value.i;
206                         return CONTACTS_ERROR_NONE;
207                 }
208         }
209
210         return CONTACTS_ERROR_NO_DATA;
211 }
212 /* LCOV_EXCL_STOP */
213
214 static int __ctsvc_result_set_int(contacts_record_h record, unsigned int property_id, int value, bool *is_dirty)
215 {
216         ctsvc_result_s *result = (ctsvc_result_s*)record;
217         GSList *cursor;
218         ctsvc_result_value_s *data;
219
220         if (CTSVC_VIEW_DATA_TYPE_INT != (CTSVC_VIEW_DATA_TYPE_INT & property_id)) {
221                 /* LCOV_EXCL_START */
222                 ERR("property_id is not int type.");
223                 return CONTACTS_ERROR_INVALID_PARAMETER;
224                 /* LCOV_EXCL_STOP */
225         }
226
227         for (cursor = result->values; cursor; cursor = cursor->next) {
228                 data = cursor->data;
229                 if (data->property_id == property_id) {
230 #ifdef _CONTACTS_IPC_SERVER
231                         /* LCOV_EXCL_START */
232                         if (CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO == property_id
233                                         || CTSVC_PROPERTY_PHONELOG_STAT_SIM_SLOT_NO == property_id) {
234                                 CHECK_DIRTY_VAL(data->value.i, value, is_dirty);
235                                 data->value.i = ctsvc_server_sim_get_sim_slot_no_by_info_id(value);
236                         } else
237 #endif /* _CONTACTS_IPC_SERVER */
238                         {
239                                 CHECK_DIRTY_VAL(data->value.i, value, is_dirty);
240                                 data->value.i = value;
241                         }
242                         return CONTACTS_ERROR_NONE;
243                         /* LCOV_EXCL_STOP */
244                 }
245         }
246
247         data = calloc(1, sizeof(ctsvc_result_value_s));
248         if (NULL == data) {
249                 /* LCOV_EXCL_START */
250                 ERR("calloc() Fail");
251                 return CONTACTS_ERROR_OUT_OF_MEMORY;
252                 /* LCOV_EXCL_STOP */
253         }
254         data->property_id = property_id;
255         data->type = CTSVC_VIEW_DATA_TYPE_INT;
256 #ifdef _CONTACTS_IPC_SERVER
257         if (CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO == property_id
258                         || CTSVC_PROPERTY_PHONELOG_STAT_SIM_SLOT_NO == property_id) {
259                 CHECK_DIRTY_VAL(data->value.i, value, is_dirty);
260                 data->value.i = ctsvc_server_sim_get_sim_slot_no_by_info_id(value);
261         } else
262 #endif /* _CONTACTS_IPC_SERVER */
263         {
264                 CHECK_DIRTY_VAL(data->value.i, value, is_dirty);
265                 data->value.i = value;
266         }
267         result->values = g_slist_append(result->values, (void*)data);
268         return CONTACTS_ERROR_NONE;
269 }
270
271 /* LCOV_EXCL_START */
272 static int __ctsvc_result_set_bool(contacts_record_h record, unsigned int property_id, bool value, bool *is_dirty)
273 {
274         ctsvc_result_s *result = (ctsvc_result_s*)record;
275         GSList *cursor;
276         ctsvc_result_value_s *data;
277
278         /* TODO: check the value type of property_id is int */
279         for (cursor = result->values; cursor; cursor = cursor->next) {
280                 data = cursor->data;
281                 if (data->property_id == property_id) {
282                         if (data->type == CTSVC_VIEW_DATA_TYPE_BOOL) {
283                                 CHECK_DIRTY_VAL(data->value.b, value, is_dirty);
284                                 data->value.b = value;
285                                 return CONTACTS_ERROR_NONE;
286                         } else {
287                                 ERR("use another get_type API, (type : %d)", data->type);
288                                 return CONTACTS_ERROR_INVALID_PARAMETER;
289                         }
290                 }
291         }
292
293         data = calloc(1, sizeof(ctsvc_result_value_s));
294         if (NULL == data) {
295                 ERR("calloc() Fail");
296                 return CONTACTS_ERROR_OUT_OF_MEMORY;
297         }
298         data->property_id = property_id;
299         data->type = CTSVC_VIEW_DATA_TYPE_BOOL;
300         CHECK_DIRTY_VAL(data->value.b, value, is_dirty);
301         data->value.b = value;
302         result->values = g_slist_append(result->values, (void*)data);
303         return CONTACTS_ERROR_NONE;
304 }
305
306 static int __ctsvc_result_set_str(contacts_record_h record, unsigned int property_id, const char *str, bool *is_dirty)
307 {
308         ctsvc_result_s *result = (ctsvc_result_s*)record;
309         GSList *cursor;
310         ctsvc_result_value_s *data;
311         char *full_path = NULL;
312         int str_len;
313
314         if (CTSVC_VIEW_DATA_TYPE_STR != (CTSVC_VIEW_DATA_TYPE_STR & property_id)) {
315                 ERR("property_id is not str type.");
316                 return CONTACTS_ERROR_INVALID_PARAMETER;
317         }
318
319         for (cursor = result->values; cursor; cursor = cursor->next) {
320                 data = cursor->data;
321                 if (data->property_id == property_id) {
322                         switch (property_id) {
323                         case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
324                         case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
325                                 if (str) {
326                                         str_len = strlen(CTSVC_CONTACT_IMG_FULL_LOCATION) + strlen(str) + 2;
327                                         full_path = calloc(1, str_len);
328                                         if (NULL == full_path) {
329                                                 ERR("calloc() Fail");
330                                                 return CONTACTS_ERROR_OUT_OF_MEMORY;
331                                         }
332                                         snprintf(full_path, str_len, "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, str);
333                                 }
334                                 CHECK_DIRTY_STR(data->value.s, full_path, is_dirty);
335                                 free(data->value.s);
336                                 data->value.s = full_path;
337                                 return CONTACTS_ERROR_NONE;
338                         default:
339                                 CHECK_DIRTY_STR(data->value.s, str, is_dirty);
340                                 FREEandSTRDUP(data->value.s, str);
341                                 return CONTACTS_ERROR_NONE;
342                         }
343                 }
344         }
345
346         data = calloc(1, sizeof(ctsvc_result_value_s));
347         if (NULL == data) {
348                 ERR("calloc() Fail");
349                 return CONTACTS_ERROR_OUT_OF_MEMORY;
350         }
351         data->property_id = property_id;
352         data->type = CTSVC_VIEW_DATA_TYPE_STR;
353         switch (property_id) {
354         case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
355         case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
356                 if (str) {
357                         str_len = strlen(CTSVC_CONTACT_IMG_FULL_LOCATION) + strlen(str) + 2;
358                         full_path = calloc(1, str_len);
359                         if (NULL == full_path) {
360                                 ERR("calloc() Fail");
361                                 free(data);
362                                 return CONTACTS_ERROR_OUT_OF_MEMORY;
363                         }
364                         snprintf(full_path, str_len, "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, str);
365                 }
366                 CHECK_DIRTY_STR(data->value.s, full_path, is_dirty);
367                 free(data->value.s);
368                 data->value.s = full_path;
369                 break;
370         default:
371                 CHECK_DIRTY_STR(data->value.s, str, is_dirty);
372                 data->value.s = SAFE_STRDUP(str);
373                 break;
374         }
375
376         result->values = g_slist_append(result->values, (void*)data);
377         return CONTACTS_ERROR_NONE;
378 }
379
380 static int __ctsvc_result_get_bool(contacts_record_h record, unsigned int property_id, bool *out_value)
381 {
382         ctsvc_result_s *result = (ctsvc_result_s*)record;
383         GSList *cursor;
384         for (cursor = result->values; cursor; cursor = cursor->next) {
385                 ctsvc_result_value_s *data = cursor->data;
386                 if (data->property_id == property_id) {
387                         if (data->type == CTSVC_VIEW_DATA_TYPE_BOOL) {
388                                 *out_value = data->value.b;
389                                 return CONTACTS_ERROR_NONE;
390                         } else {
391                                 ERR("use another get_type API, (type : %d)", data->type);
392                                 return CONTACTS_ERROR_INVALID_PARAMETER;
393                         }
394                 }
395         }
396
397         return CONTACTS_ERROR_NO_DATA;
398 }
399 /* LCOV_EXCL_STOP */