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_list.h"
24 #include "ctsvc_record.h"
26 EXPORT_API int contacts_list_create(contacts_list_h *out_list)
28 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
31 RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
34 list_s = calloc(1, sizeof(ctsvc_list_s));
35 RETVM_IF(NULL == list_s, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() Fail");
38 *out_list = (contacts_list_h)list_s;
39 return CONTACTS_ERROR_NONE;
42 EXPORT_API int contacts_list_get_count(contacts_list_h list, int *count)
44 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
47 RETV_IF(NULL == count, CONTACTS_ERROR_INVALID_PARAMETER);
50 RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
51 list_s = (ctsvc_list_s*)list;
53 *count = list_s->count;
54 return CONTACTS_ERROR_NONE;
57 int ctsvc_list_add_child(contacts_list_h list, contacts_record_h child_record)
60 ctsvc_record_s *s_record;
62 RETV_IF(NULL == list || NULL == child_record, CONTACTS_ERROR_INVALID_PARAMETER);
63 s_list = (ctsvc_list_s*)list;
64 s_record = (ctsvc_record_s*)child_record;
66 if (-1 == s_list->l_type)
67 s_list->l_type = s_record->r_type;
68 else if (s_list->l_type != s_record->r_type)
69 return CONTACTS_ERROR_INVALID_PARAMETER;
71 s_list->records = g_list_append(s_list->records, child_record);
73 if (s_list->count == 0)
74 s_list->cursor = s_list->records;
77 return CONTACTS_ERROR_NONE;
80 EXPORT_API int contacts_list_add(contacts_list_h list, contacts_record_h child_record)
82 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
84 ctsvc_record_s *s_record;
86 RETV_IF(NULL == list || NULL == child_record, CONTACTS_ERROR_INVALID_PARAMETER);
87 s_list = (ctsvc_list_s*)list;
88 s_record = (ctsvc_record_s*)child_record;
90 if (-1 == s_list->l_type)
91 s_list->l_type = s_record->r_type;
92 else if (s_list->l_type != s_record->r_type)
93 return CONTACTS_ERROR_INVALID_PARAMETER;
95 s_list->records = g_list_append(s_list->records, child_record);
97 if (s_list->count == 0)
98 s_list->cursor = s_list->records;
101 return CONTACTS_ERROR_NONE;
104 int ctsvc_list_prepend(contacts_list_h list, contacts_record_h child_record)
106 ctsvc_list_s *s_list;
107 ctsvc_record_s *s_record;
109 RETV_IF(NULL == list || NULL == child_record, CONTACTS_ERROR_INVALID_PARAMETER);
110 s_list = (ctsvc_list_s*)list;
111 s_record = (ctsvc_record_s*)child_record;
113 if (-1 == s_list->l_type)
114 s_list->l_type = s_record->r_type;
115 else if (s_list->l_type != s_record->r_type)
116 return CONTACTS_ERROR_INVALID_PARAMETER;
118 s_list->records = g_list_prepend(s_list->records, child_record);
120 if (s_list->count == 0)
121 s_list->cursor = s_list->records;
124 return CONTACTS_ERROR_NONE;
127 int ctsvc_list_reverse(contacts_list_h list)
129 ctsvc_list_s *s_list;
131 RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
132 s_list = (ctsvc_list_s*)list;
134 if (s_list->count != 0)
135 s_list->records = g_list_reverse(s_list->records);
137 return CONTACTS_ERROR_NONE;
140 int ctsvc_list_remove_child(contacts_list_h list, contacts_record_h record,
141 bool insert_delete_list)
143 GList *cursor = NULL;
144 ctsvc_list_s *s_list;
145 ctsvc_record_s *s_record;
146 contacts_record_h delete_record;
147 contacts_error_e err = CONTACTS_ERROR_NONE;
149 RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
150 s_list = (ctsvc_list_s*)list;
151 s_record = (ctsvc_record_s*)record;
153 if (s_list->l_type != s_record->r_type)
154 return CONTACTS_ERROR_INVALID_PARAMETER;
156 for (cursor = s_list->records; cursor; cursor = cursor->next) {
157 ctsvc_record_s *data = cursor->data;
158 if (data == s_record) {
160 if (s_list->cursor == cursor)
161 s_list->cursor = cursor->next;
163 s_list->records = g_list_remove(s_list->records, s_record);
164 if (insert_delete_list) {
165 err = contacts_record_clone(record, &delete_record);
166 if (CONTACTS_ERROR_NONE != err) {
167 /* LCOV_EXCL_START */
168 ERR("contacts_record_clone() Fail(%d)", err);
173 s_list->deleted_records = g_list_append(s_list->deleted_records, delete_record);
175 return CONTACTS_ERROR_NONE;
179 return CONTACTS_ERROR_NO_DATA;
182 EXPORT_API int contacts_list_remove(contacts_list_h list, contacts_record_h record)
184 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
185 GList *cursor = NULL;
186 ctsvc_list_s *s_list;
187 ctsvc_record_s *s_record;
189 RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
190 s_list = (ctsvc_list_s*)list;
191 s_record = (ctsvc_record_s*)record;
193 if (s_list->l_type != s_record->r_type)
194 return CONTACTS_ERROR_INVALID_PARAMETER;
196 for (cursor = s_list->records; cursor; cursor = cursor->next) {
197 ctsvc_record_s *data = cursor->data;
198 if (data == s_record) {
200 if (s_list->cursor == cursor)
201 s_list->cursor = cursor->next;
202 s_list->records = g_list_remove(s_list->records, s_record);
203 return CONTACTS_ERROR_NONE;
207 return CONTACTS_ERROR_NO_DATA;
210 EXPORT_API int contacts_list_get_current_record_p(contacts_list_h list, contacts_record_h *record)
212 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
213 ctsvc_list_s *list_s;
215 RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
218 RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
219 list_s = (ctsvc_list_s*)list;
221 if (NULL == list_s->cursor) {
223 return CONTACTS_ERROR_NO_DATA;
226 *record = list_s->cursor->data;
228 return CONTACTS_ERROR_NONE;
231 int ctsvc_list_get_nth_record_p(contacts_list_h list, int index, contacts_record_h *record)
233 GList *cursor = NULL;
234 ctsvc_list_s *list_s;
237 RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
240 RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
241 list_s = (ctsvc_list_s*)list;
243 for (i = 0, j = 0, cursor = list_s->records; cursor; cursor = cursor->next, i++) {
245 *record = cursor->data;
246 return CONTACTS_ERROR_NONE;
251 return CONTACTS_ERROR_NO_DATA;
254 static int __ctsvc_list_move_cursor(contacts_list_h list, bool next)
256 ctsvc_list_s *list_s;
258 RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
259 list_s = (ctsvc_list_s*)list;
261 if (NULL == list_s->cursor)
262 return CONTACTS_ERROR_NO_DATA;
264 list_s->cursor = next ? list_s->cursor->next : list_s->cursor->prev ;
266 if (NULL == list_s->cursor)
267 return CONTACTS_ERROR_NO_DATA;
269 return CONTACTS_ERROR_NONE;
272 EXPORT_API int contacts_list_prev(contacts_list_h list)
274 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
275 return __ctsvc_list_move_cursor(list, false);
278 EXPORT_API int contacts_list_next(contacts_list_h list)
280 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
281 return __ctsvc_list_move_cursor(list, true);
286 EXPORT_API int contacts_list_first(contacts_list_h list)
288 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
289 ctsvc_list_s *list_s;
291 RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
292 list_s = (ctsvc_list_s*)list;
294 list_s->cursor = list_s->records;
295 if (NULL == list_s->cursor)
296 return CONTACTS_ERROR_NO_DATA;
298 return CONTACTS_ERROR_NONE;
301 EXPORT_API int contacts_list_last(contacts_list_h list)
303 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
304 ctsvc_list_s *list_s;
306 RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
307 list_s = (ctsvc_list_s*)list;
309 list_s->cursor = g_list_last(list_s->records);
310 if (NULL == list_s->cursor)
311 return CONTACTS_ERROR_NO_DATA;
313 return CONTACTS_ERROR_NONE;
316 EXPORT_API int contacts_list_destroy(contacts_list_h list, bool delete_child)
318 CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
319 ctsvc_list_s *s_list;
320 GList *cursor = NULL;
322 RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
324 s_list = (ctsvc_list_s*)list;
327 for (cursor = s_list->records; cursor; cursor = cursor->next)
328 contacts_record_destroy((contacts_record_h)(cursor->data), true);
330 g_list_free(s_list->records);
332 for (cursor = s_list->deleted_records; cursor; cursor = cursor->next)
333 contacts_record_destroy((contacts_record_h)(cursor->data), true);
334 g_list_free(s_list->deleted_records);
337 return CONTACTS_ERROR_NONE;
340 int ctsvc_list_clone(contacts_list_h list, contacts_list_h *out_list)
342 ctsvc_list_s *list_s;
343 contacts_record_h new_record;
344 contacts_list_h new_list;
345 GList *cursor = NULL;
346 contacts_error_e err = CONTACTS_ERROR_NONE;
348 RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
350 list_s = (ctsvc_list_s*)list;
352 contacts_list_create(&new_list);
353 for (cursor = list_s->records; cursor; cursor = cursor->next) {
354 err = contacts_record_clone(cursor->data, &new_record);
355 if (CONTACTS_ERROR_NONE != err) {
356 /* LCOV_EXCL_START */
357 ERR("contacts_record_clone() Fail(%d)", err);
358 contacts_list_destroy(new_list, true);
362 ctsvc_list_prepend(new_list, new_record);
364 ctsvc_list_reverse(new_list);
366 for (cursor = list_s->deleted_records; cursor; cursor = cursor->next) {
367 err = contacts_record_clone(cursor->data, &new_record);
368 if (CONTACTS_ERROR_NONE != err) {
369 /* LCOV_EXCL_START */
370 ERR("contacts_record_clone() Fail(%d)", err);
371 contacts_list_destroy(new_list, true);
375 ((ctsvc_list_s*)new_list)->deleted_records
376 = g_list_prepend(((ctsvc_list_s*)new_list)->deleted_records, new_record);
378 if (((ctsvc_list_s*)new_list)->deleted_records) {
379 ((ctsvc_list_s*)new_list)->deleted_records
380 = g_list_reverse(((ctsvc_list_s*)new_list)->deleted_records);
383 *out_list = new_list;
385 return CONTACTS_ERROR_NONE;
389 int ctsvc_list_get_deleted_count(contacts_list_h list, unsigned int *count)
391 ctsvc_list_s *list_s;
393 RETV_IF(NULL == count, CONTACTS_ERROR_INVALID_PARAMETER);
396 RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
397 list_s = (ctsvc_list_s*)list;
399 if (NULL == list_s->deleted_records)
400 return CONTACTS_ERROR_NONE;
402 *count = g_list_length(list_s->deleted_records);
404 return CONTACTS_ERROR_NONE;
407 int ctsvc_list_get_deleted_nth_record_p(contacts_list_h list, int index,
408 contacts_record_h *record)
410 ctsvc_list_s *list_s;
412 RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
415 RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
416 list_s = (ctsvc_list_s*)list;
418 RETV_IF(NULL == list_s->deleted_records, CONTACTS_ERROR_NO_DATA);
420 *record = (contacts_record_h)g_list_nth_data(list_s->deleted_records, index);
422 return CONTACTS_ERROR_NONE;
425 int ctsvc_list_append_deleted_record(contacts_list_h list, contacts_record_h record)
427 ctsvc_list_s *list_s;
429 RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
431 list_s = (ctsvc_list_s*)list;
433 list_s->deleted_records = g_list_append(list_s->deleted_records, record);
435 return CONTACTS_ERROR_NONE;