Add LCOV remarkers to increase line coverage rate
[platform/core/api/maps-service.git] / src / api / maps_place.cpp
1 /* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <glib.h>
17 #include "maps_error.h"
18 #include "maps_place_plugin.h"
19 #include "maps_extra_types.h"
20 #include "maps_util.h"
21 #include "maps_address.h"
22 #include "maps_place_private.h"
23 #include "maps_condition.h"
24
25 static bool __is_supported(const maps_place_h place, maps_service_data_e data)
26 {
27         bool supported = false;
28         _maps_place_is_data_supported(place, data, &supported);
29         return supported;
30 }
31
32 /*----------------------------------------------------------------------------*/
33
34 typedef struct _maps_place_s
35 {
36         char *id;
37         char *name;
38         char *uri;
39
40         maps_coordinates_h location;
41
42         int distance;
43
44         maps_address_h address;
45
46         maps_place_rating_h rating;
47
48         /* List of properties:
49          * Obtained with: maps_place_properties_cb callback
50          * Items are pairs: const char* key, const char* value */
51         maps_item_hashtable_h properties;
52
53         /* List of categories
54          * Obtained with: maps_place_categories_cb
55          * Each of type: maps_place_category_h */
56         maps_item_list_h categories;
57
58         /* List of attributes
59         * Obtained with maps_place_attributes_cb
60         * Each of type: maps_place_attribute_h */
61         maps_item_list_h attribute;
62
63         /* List of contacts
64          * Obtained with: maps_place_contacts_cb
65          * Each of type: maps_place_contact_h */
66         maps_item_list_h contacts;
67
68         /* List of editorials
69          * Obtained with: maps_place_editorials_cb
70          * Each of type: maps_place_editorial_h */
71         maps_item_list_h editorials;
72
73         /* List of images
74          * Obtained with: maps_place_images_cb callback
75          * Each of type: maps_place_image_h */
76         maps_item_list_h images;
77
78         /* List of reviews
79          * Obtained with: maps_place_reviews_cb callback
80          * Each of type: maps_place_review_h */
81         maps_item_list_h reviews;
82
83         maps_place_link_object_h supplier;
84         maps_place_link_object_h related;
85
86         /* The table of available data features */
87         maps_int_hashtable_h supported_data;
88 } maps_place_s;
89
90 /* TODO: extract all such constants to the dedcated header file */
91 const gsize _MAPS_PLACE_ID_MAX_LENGTH = MAPS_BASE_ID_MAX_LEN;
92 const gsize _MAPS_PLACE_NAME_MAX_LENGTH = MAPS_BASE_NAME_MAX_LEN;
93 const gsize _MAPS_PLACE_URI_MAX_LENGTH = MAPS_BASE_URL_MAX_LEN;
94
95 /*----------------------------------------------------------------------------*/
96
97 EXPORT_API int maps_place_create(maps_place_h *place)
98 {
99         if (!maps_condition_check_maps_feature())
100                 return MAPS_ERROR_NOT_SUPPORTED;
101         if (!place)
102                 return MAPS_ERROR_INVALID_PARAMETER;
103         *place = (maps_place_h) g_slice_new0(maps_place_s);
104
105         if (*place == NULL) {
106                 //LCOV_EXCL_START
107                 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
108                 return MAPS_ERROR_OUT_OF_MEMORY;
109                 //LCOV_EXCL_STOP
110         }
111
112         return MAPS_ERROR_NONE;
113 }
114
115 EXPORT_API int maps_place_destroy(maps_place_h place)
116 {
117         if (!maps_condition_check_maps_feature())
118                 return MAPS_ERROR_NOT_SUPPORTED;
119         if (!place)
120                 return MAPS_ERROR_INVALID_PARAMETER;
121
122         maps_place_s *p = (maps_place_s *) place;
123
124         if (p->id)
125                 g_free(p->id);
126         if (p->name)
127                 g_free(p->name);
128         if (p->uri)
129                 g_free(p->uri);
130
131         if (p->location)
132                 maps_coordinates_destroy(p->location);
133
134         if (p->address)
135                 maps_address_destroy(p->address);
136
137         if (p->rating)
138                 maps_place_rating_destroy(p->rating);
139
140         if (p->properties)
141                 maps_item_hashtable_destroy(p->properties);
142
143         if (p->categories) {
144                 maps_item_list_remove_all(p->categories,
145                         maps_place_category_destroy);
146                 maps_item_list_destroy(p->categories);
147         }
148
149         if (p->attribute) {
150                 maps_item_list_remove_all(p->attribute,
151                         maps_place_attribute_destroy);
152                 maps_item_list_destroy(p->attribute);
153         }
154
155         if (p->contacts) {
156                 maps_item_list_remove_all(p->contacts,
157                         maps_place_contact_destroy);
158                 maps_item_list_destroy(p->contacts);
159         }
160
161         if (p->editorials) {
162                 maps_item_list_remove_all(p->editorials,
163                         maps_place_editorial_destroy);
164                 maps_item_list_destroy(p->editorials);
165         }
166
167         if (p->images) {
168                 maps_item_list_remove_all(p->images, maps_place_image_destroy);
169                 maps_item_list_destroy(p->images);
170         }
171
172         if (p->reviews) {
173                 maps_item_list_remove_all(p->reviews,
174                         maps_place_review_destroy);
175                 maps_item_list_destroy(p->reviews);
176         }
177
178         if (p->supplier)
179                 maps_place_link_object_destroy(p->supplier);
180         if (p->related)
181                 maps_place_link_object_destroy(p->related);
182
183         if (p->supported_data)
184                 maps_int_hashtable_destroy(p->supported_data);
185
186         g_slice_free(maps_place_s, place);
187         return MAPS_ERROR_NONE;
188 }
189
190 EXPORT_API int maps_place_clone(const maps_place_h origin,
191                                 maps_place_h *cloned)
192 {
193         if (!maps_condition_check_maps_feature())
194                 return MAPS_ERROR_NOT_SUPPORTED;
195         if (!cloned || !origin)
196                 return MAPS_ERROR_INVALID_PARAMETER;
197
198         int error = MAPS_ERROR_NONE;
199         do {
200                 error = maps_place_create(cloned);
201                 if (!(*cloned) || (error != MAPS_ERROR_NONE))
202                         break;
203
204                 maps_place_s *p = (maps_place_s *) origin;
205
206                 if (p->id) {
207                         error = maps_place_set_id(*cloned, p->id);
208                         if (error != MAPS_ERROR_NONE)
209                                 break;
210                 }
211
212                 if (p->name) {
213                         error = maps_place_set_name(*cloned, p->name);
214                         if (error != MAPS_ERROR_NONE)
215                                 break;
216                 }
217
218                 if (p->uri) {
219                         error = maps_place_set_uri(*cloned, p->uri);
220                         if (error != MAPS_ERROR_NONE)
221                                 break;
222                 }
223
224                 if (p->location) {
225                         error = maps_place_set_location(*cloned, p->location);
226                         if (error != MAPS_ERROR_NONE)
227                                 break;
228                 }
229
230                 error = maps_place_set_distance(*cloned, p->distance);
231                 if (error != MAPS_ERROR_NONE)
232                         break;
233
234                 if (p->address) {
235                         error = maps_place_set_address(*cloned, p->address);
236                         if (error != MAPS_ERROR_NONE)
237                                 break;
238                 }
239
240                 if (p->rating) {
241                         error = maps_place_set_rating(*cloned, p->rating);
242                         if (error != MAPS_ERROR_NONE)
243                                 break;
244                 }
245
246                 if (p->properties) {
247                         error = maps_place_set_properties(*cloned, p->properties);
248                         if (error != MAPS_ERROR_NONE)
249                                 break;
250                 }
251
252                 if (p->categories) {
253                         error = maps_place_set_categories(*cloned, p->categories);
254                         if (error != MAPS_ERROR_NONE)
255                                 break;
256                 }
257
258                 if (p->attribute) {
259                         error = maps_place_set_attributes(*cloned, p->attribute);
260                         if (error != MAPS_ERROR_NONE)
261                                 break;
262                 }
263
264                 if (p->contacts) {
265                         error = maps_place_set_contacts(*cloned, p->contacts);
266                         if (error != MAPS_ERROR_NONE)
267                                 break;
268                 }
269
270                 if (p->editorials) {
271                         error = maps_place_set_editorials(*cloned, p->editorials);
272                         if (error != MAPS_ERROR_NONE)
273                                 break;
274                 }
275
276                 if (p->images) {
277                         error = maps_place_set_images(*cloned, p->images);
278                         if (error != MAPS_ERROR_NONE)
279                                 break;
280                 }
281
282                 if (p->reviews) {
283                         error = maps_place_set_reviews(*cloned, p->reviews);
284                         if (error != MAPS_ERROR_NONE)
285                                 break;
286                 }
287
288                 if (p->supplier) {
289                         error = maps_place_set_supplier_link(*cloned, p->supplier);
290                         if (error != MAPS_ERROR_NONE)
291                                 break;
292                 }
293
294                 if (p->related) {
295                         error = maps_place_set_related_link(*cloned, p->related);
296                         if (error != MAPS_ERROR_NONE)
297                                 break;
298                 }
299
300                 if (p->supported_data) {
301                         error = _maps_place_set_supported_data(*cloned, p->supported_data);
302                         if (error != MAPS_ERROR_NONE)
303                                 break;
304                 }
305
306                 return MAPS_ERROR_NONE;
307         } while (false);
308
309         //LCOV_EXCL_START
310         maps_place_destroy(*cloned);
311         *cloned = NULL;
312         return error;
313         //LCOV_EXCL_STOP
314 }
315
316 /*----------------------------------------------------------------------------*/
317
318 EXPORT_API int maps_place_get_id(const maps_place_h place, char **id)
319 {
320         if (!maps_condition_check_maps_feature())
321                 return MAPS_ERROR_NOT_SUPPORTED;
322         if (!place || !id)
323                 return MAPS_ERROR_INVALID_PARAMETER;
324         if (!((maps_place_s *) place)->id)
325                 return MAPS_ERROR_NOT_FOUND;
326         return maps_get_string(((maps_place_s *) place)->id,
327                 _MAPS_PLACE_ID_MAX_LENGTH, id);
328 }
329
330 EXPORT_API int maps_place_get_name(const maps_place_h place, char **name)
331 {
332         if (!maps_condition_check_maps_feature())
333                 return MAPS_ERROR_NOT_SUPPORTED;
334         if (!place || !name)
335                 return MAPS_ERROR_INVALID_PARAMETER;
336         if (!((maps_place_s *) place)->name)
337                 return MAPS_ERROR_NOT_FOUND;
338         return maps_get_string(((maps_place_s *) place)->name,
339                 _MAPS_PLACE_NAME_MAX_LENGTH, name);
340 }
341
342 EXPORT_API int maps_place_get_uri(const maps_place_h place, char **uri)
343 {
344         if (!maps_condition_check_maps_feature())
345                 return MAPS_ERROR_NOT_SUPPORTED;
346         if (!place || !uri)
347                 return MAPS_ERROR_INVALID_PARAMETER;
348         if (!((maps_place_s *) place)->uri)
349                 return MAPS_ERROR_NOT_FOUND;
350         return maps_get_string(((maps_place_s *) place)->uri,
351                 _MAPS_PLACE_URI_MAX_LENGTH, uri);
352 }
353
354 EXPORT_API int maps_place_get_location(const maps_place_h place,
355                                                                 maps_coordinates_h *location)
356 {
357         if (!maps_condition_check_maps_feature())
358                 return MAPS_ERROR_NOT_SUPPORTED;
359         if (!place || !location)
360                 return MAPS_ERROR_INVALID_PARAMETER;
361         if (!((maps_place_s *) place)->location)
362                 return MAPS_ERROR_NOT_FOUND;
363         return maps_coordinates_clone(((maps_place_s *) place)->location,
364                 location);
365 }
366
367 EXPORT_API int maps_place_get_distance(const maps_place_h place, int *distance)
368 {
369         if (!maps_condition_check_maps_feature())
370                 return MAPS_ERROR_NOT_SUPPORTED;
371         if (!place || !distance)
372                 return MAPS_ERROR_INVALID_PARAMETER;
373         *distance = ((maps_place_s *) place)->distance;
374         return MAPS_ERROR_NONE;
375 }
376
377 EXPORT_API int maps_place_get_address(const maps_place_h place,
378                                                                 maps_address_h *address)
379 {
380         if (!maps_condition_check_maps_feature())
381                 return MAPS_ERROR_NOT_SUPPORTED;
382         if (!place)
383                 return MAPS_ERROR_INVALID_PARAMETER;
384         if (!__is_supported(place, MAPS_PLACE_ADDRESS))
385                 return MAPS_ERROR_NOT_SUPPORTED;
386         if (!address)
387                 return MAPS_ERROR_INVALID_PARAMETER;
388         if (!((maps_place_s *) place)->address)
389                 return MAPS_ERROR_NOT_FOUND;
390         return maps_address_clone(((maps_place_s *) place)->address, address);
391 }
392
393 EXPORT_API int maps_place_get_rating(const maps_place_h place,
394                                                                 maps_place_rating_h *rating)
395 {
396         if (!maps_condition_check_maps_feature())
397                 return MAPS_ERROR_NOT_SUPPORTED;
398         if (!place)
399                 return MAPS_ERROR_INVALID_PARAMETER;
400         if (!__is_supported(place, MAPS_PLACE_RATING))
401                 return MAPS_ERROR_NOT_SUPPORTED;
402         if (!rating)
403                 return MAPS_ERROR_INVALID_PARAMETER;
404         if (!((maps_place_s *) place)->rating)
405                 return MAPS_ERROR_NOT_FOUND;
406         return maps_place_rating_clone(((maps_place_s *) place)->rating, rating);
407 }
408
409 EXPORT_API int maps_place_foreach_property(const maps_place_h place,
410                                                                 maps_place_properties_cb callback,
411                                                                 void *user_data)
412 {
413         if (!maps_condition_check_maps_feature())
414                 return MAPS_ERROR_NOT_SUPPORTED;
415         if (!place || !callback)
416                 return MAPS_ERROR_INVALID_PARAMETER;
417         if (!((maps_place_s *) place)->properties)
418                 return MAPS_ERROR_NOT_FOUND;
419         return maps_item_hashtable_foreach(((maps_place_s *) place)->properties,
420                 callback, user_data);
421 }
422
423 EXPORT_API int maps_place_foreach_category(const maps_place_h place,
424                                                                 maps_place_categories_cb callback,
425                                                                 void *user_data)
426 {
427         if (!maps_condition_check_maps_feature())
428                 return MAPS_ERROR_NOT_SUPPORTED;
429         if (!place)
430                 return MAPS_ERROR_INVALID_PARAMETER;
431         if (!__is_supported(place, MAPS_PLACE_CATEGORIES))
432                 return MAPS_ERROR_NOT_SUPPORTED;
433         if (!callback)
434                 return MAPS_ERROR_INVALID_PARAMETER;
435         if (!((maps_place_s *) place)->categories)
436                 return MAPS_ERROR_NOT_FOUND;
437         return maps_item_list_foreach(((maps_place_s *) place)->categories,
438                 maps_place_category_clone, callback, user_data);
439 }
440
441 EXPORT_API int maps_place_foreach_attribute(const maps_place_h place,
442                                                                 maps_place_attributes_cb callback,
443                                                                 void * user_data)
444 {
445         if (!maps_condition_check_maps_feature())
446                 return MAPS_ERROR_NOT_SUPPORTED;
447         if (!place)
448                 return MAPS_ERROR_INVALID_PARAMETER;
449         if (!__is_supported(place, MAPS_PLACE_ATTRIBUTES))
450                 return MAPS_ERROR_NOT_SUPPORTED;
451         if (!callback)
452                 return MAPS_ERROR_INVALID_PARAMETER;
453         if (!((maps_place_s *) place)->attribute)
454                 return MAPS_ERROR_NOT_FOUND;
455         return maps_item_list_foreach(((maps_place_s *) place)->attribute,
456                 maps_place_attribute_clone, callback, user_data);
457 }
458
459 EXPORT_API int maps_place_foreach_contact(const maps_place_h place,
460                                                                 maps_place_contacts_cb callback,
461                                                                 void *user_data)
462 {
463         if (!maps_condition_check_maps_feature())
464                 return MAPS_ERROR_NOT_SUPPORTED;
465         if (!place)
466                 return MAPS_ERROR_INVALID_PARAMETER;
467         if (!__is_supported(place, MAPS_PLACE_CONTACTS))
468                 return MAPS_ERROR_NOT_SUPPORTED;
469         if (!callback)
470                 return MAPS_ERROR_INVALID_PARAMETER;
471         if (!((maps_place_s *) place)->contacts)
472                 return MAPS_ERROR_NOT_FOUND;
473         return maps_item_list_foreach(((maps_place_s *) place)->contacts,
474                 maps_place_contact_clone, callback, user_data);
475 }
476
477 EXPORT_API int maps_place_foreach_editorial(const maps_place_h place,
478                                                                 maps_place_editorials_cb callback,
479                                                                 void *user_data)
480 {
481         if (!maps_condition_check_maps_feature())
482                 return MAPS_ERROR_NOT_SUPPORTED;
483         if (!place)
484                 return MAPS_ERROR_INVALID_PARAMETER;
485         if (!__is_supported(place, MAPS_PLACE_EDITORIALS))
486                 return MAPS_ERROR_NOT_SUPPORTED;
487         if (!callback)
488                 return MAPS_ERROR_INVALID_PARAMETER;
489         if (!((maps_place_s *) place)->editorials)
490                 return MAPS_ERROR_NOT_FOUND;
491         return maps_item_list_foreach(((maps_place_s *) place)->editorials,
492                 maps_place_editorial_clone, callback, user_data);
493 }
494
495 EXPORT_API int maps_place_foreach_image(const maps_place_h place,
496                                                                 maps_place_images_cb callback,
497                                                                 void *user_data)
498 {
499         if (!maps_condition_check_maps_feature())
500                 return MAPS_ERROR_NOT_SUPPORTED;
501         if (!place)
502                 return MAPS_ERROR_INVALID_PARAMETER;
503         if (!__is_supported(place, MAPS_PLACE_IMAGE))
504                 return MAPS_ERROR_NOT_SUPPORTED;
505         if (!callback)
506                 return MAPS_ERROR_INVALID_PARAMETER;
507         if (!((maps_place_s *) place)->images)
508                 return MAPS_ERROR_NOT_FOUND;
509         return maps_item_list_foreach(((maps_place_s *) place)->images,
510                 maps_place_image_clone, callback, user_data);
511 }
512
513 EXPORT_API int maps_place_foreach_review(const maps_place_h place,
514                                                                 maps_place_reviews_cb callback,
515                                                                 void *user_data)
516 {
517         if (!maps_condition_check_maps_feature())
518                 return MAPS_ERROR_NOT_SUPPORTED;
519         if (!place)
520                 return MAPS_ERROR_INVALID_PARAMETER;
521         if (!__is_supported(place, MAPS_PLACE_REVIEWS))
522                 return MAPS_ERROR_NOT_SUPPORTED;
523         if (!callback)
524                 return MAPS_ERROR_INVALID_PARAMETER;
525         if (!((maps_place_s *) place)->reviews)
526                 return MAPS_ERROR_NOT_FOUND;
527         return maps_item_list_foreach(((maps_place_s *) place)->reviews,
528                 maps_place_review_clone, callback, user_data);
529 }
530
531 EXPORT_API int maps_place_get_supplier_link(const maps_place_h place,
532                                                                 maps_place_link_object_h *supplier)
533 {
534         if (!maps_condition_check_maps_feature())
535                 return MAPS_ERROR_NOT_SUPPORTED;
536         if (!place)
537                 return MAPS_ERROR_INVALID_PARAMETER;
538         if (!__is_supported(place, MAPS_PLACE_SUPPLIER))
539                 return MAPS_ERROR_NOT_SUPPORTED;
540         if (!supplier)
541                 return MAPS_ERROR_INVALID_PARAMETER;
542         if (!((maps_place_s *) place)->supplier)
543                 return MAPS_ERROR_NOT_FOUND;
544         return maps_place_link_object_clone(((maps_place_s *) place)->supplier, supplier);
545 }
546
547 EXPORT_API int maps_place_get_related_link(const maps_place_h place,
548                                                                 maps_place_link_object_h *related)
549 {
550         if (!maps_condition_check_maps_feature())
551                 return MAPS_ERROR_NOT_SUPPORTED;
552         if (!place)
553                 return MAPS_ERROR_INVALID_PARAMETER;
554         if (!__is_supported(place, MAPS_PLACE_RELATED))
555                 return MAPS_ERROR_NOT_SUPPORTED;
556         if (!related)
557                 return MAPS_ERROR_INVALID_PARAMETER;
558         if (!((maps_place_s *) place)->related)
559                 return MAPS_ERROR_NOT_FOUND;
560         return maps_place_link_object_clone(((maps_place_s *) place)->related, related);
561 }
562
563 int _maps_place_is_data_supported(const maps_place_h place,
564                                                                 maps_service_data_e data, bool *supported)
565 {
566         if (!maps_condition_check_maps_feature())
567                 return MAPS_ERROR_NOT_SUPPORTED;
568         if (!place || !supported)
569                 return MAPS_ERROR_INVALID_PARAMETER;
570
571         maps_place_s *p = (maps_place_s *)place;
572         if (!p->supported_data) {
573                 /* This is a case when the "supported" flags are not set yet */
574                 /* No need to limit access to fields */
575                 *supported = true;
576                 return MAPS_ERROR_NONE;
577         }
578
579         *supported = false;
580         return maps_int_hashtable_contains(p->supported_data, data, supported);
581 }
582
583 /*----------------------------------------------------------------------------*/
584
585 EXPORT_API int maps_place_set_id(maps_place_h place, const char *id)
586 {
587         if (!maps_condition_check_maps_feature())
588                 return MAPS_ERROR_NOT_SUPPORTED;
589         if (!place || !id)
590                 return MAPS_ERROR_INVALID_PARAMETER;
591         return maps_set_string(id, _MAPS_PLACE_ID_MAX_LENGTH,
592                 &((maps_place_s *) place)->id);
593 }
594
595 EXPORT_API int maps_place_set_name(maps_place_h place, const char *name)
596 {
597         if (!maps_condition_check_maps_feature())
598                 return MAPS_ERROR_NOT_SUPPORTED;
599         if (!place || !name)
600                 return MAPS_ERROR_INVALID_PARAMETER;
601         return maps_set_string(name, _MAPS_PLACE_NAME_MAX_LENGTH,
602                 &((maps_place_s *) place)->name);
603 }
604
605 EXPORT_API int maps_place_set_uri(maps_place_h place, const char *uri)
606 {
607         if (!maps_condition_check_maps_feature())
608                 return MAPS_ERROR_NOT_SUPPORTED;
609         if (!place || !uri)
610                 return MAPS_ERROR_INVALID_PARAMETER;
611         return maps_set_string(uri, _MAPS_PLACE_URI_MAX_LENGTH,
612                 &((maps_place_s *) place)->uri);
613 }
614
615 EXPORT_API int maps_place_set_location(maps_place_h place, const maps_coordinates_h location)
616 {
617         if (!maps_condition_check_maps_feature())
618                 return MAPS_ERROR_NOT_SUPPORTED;
619         if (!place || !location)
620                 return MAPS_ERROR_INVALID_PARAMETER;
621         maps_place_s *p = (maps_place_s *) place;
622         if (p->location)
623                 maps_coordinates_destroy(p->location);
624         return maps_coordinates_clone(location, &p->location);
625 }
626
627 EXPORT_API int maps_place_set_distance(maps_place_h place, const int distance)
628 {
629         if (!maps_condition_check_maps_feature())
630                 return MAPS_ERROR_NOT_SUPPORTED;
631         if (!place || distance < 0)
632                 return MAPS_ERROR_INVALID_PARAMETER;
633         maps_place_s *p = (maps_place_s *) place;
634         p->distance = distance;
635         return MAPS_ERROR_NONE;
636 }
637
638 EXPORT_API int maps_place_set_address(maps_place_h place, const maps_address_h address)
639 {
640         if (!maps_condition_check_maps_feature())
641                 return MAPS_ERROR_NOT_SUPPORTED;
642         if (!place || !address)
643                 return MAPS_ERROR_INVALID_PARAMETER;
644         maps_place_s *p = (maps_place_s *) place;
645         if (p->address)
646                 maps_address_destroy(p->address);
647         return maps_address_clone(address, &p->address);
648 }
649
650 EXPORT_API int maps_place_set_categories(maps_place_h place, const maps_item_list_h categories)
651 {
652         if (!maps_condition_check_maps_feature())
653                 return MAPS_ERROR_NOT_SUPPORTED;
654         if (!place || !categories)
655                 return MAPS_ERROR_INVALID_PARAMETER;
656         maps_place_s *p = (maps_place_s *) place;
657         if (p->categories) {
658                 maps_item_list_remove_all(p->categories, maps_place_category_destroy);
659                 maps_item_list_destroy(p->categories);
660         }
661         return maps_item_list_clone(categories, maps_place_category_clone, &p->categories);
662 }
663
664 EXPORT_API int maps_place_set_attributes(maps_place_h place, const maps_item_list_h attributes)
665 {
666         if (!maps_condition_check_maps_feature())
667                 return MAPS_ERROR_NOT_SUPPORTED;
668         if (!place || !attributes)
669                 return MAPS_ERROR_INVALID_PARAMETER;
670         maps_place_s *p = (maps_place_s *) place;
671         if (p->attribute) {
672                 maps_item_list_remove_all(p->attribute, maps_place_attribute_destroy);
673                 maps_item_list_destroy(p->attribute);
674         }
675         return maps_item_list_clone(attributes, maps_place_attribute_clone, &p->attribute);
676 }
677
678 EXPORT_API int maps_place_set_contacts(maps_place_h place, const maps_item_list_h contacts)
679 {
680         if (!maps_condition_check_maps_feature())
681                 return MAPS_ERROR_NOT_SUPPORTED;
682         if (!place || !contacts)
683                 return MAPS_ERROR_INVALID_PARAMETER;
684         maps_place_s *p = (maps_place_s *) place;
685         if (p->contacts) {
686                 maps_item_list_remove_all(p->contacts, maps_place_contact_destroy);
687                 maps_item_list_destroy(p->contacts);
688         }
689         return maps_item_list_clone(contacts, maps_place_contact_clone, &p->contacts);
690 }
691
692 EXPORT_API int maps_place_set_editorials(maps_place_h place, const maps_item_list_h editorials)
693 {
694         if (!maps_condition_check_maps_feature())
695                 return MAPS_ERROR_NOT_SUPPORTED;
696         if (!place || !editorials)
697                 return MAPS_ERROR_INVALID_PARAMETER;
698         maps_place_s *p = (maps_place_s *) place;
699         if (p->editorials) {
700                 maps_item_list_remove_all(p->editorials, maps_place_editorial_destroy);
701                 maps_item_list_destroy(p->editorials);
702         }
703         return maps_item_list_clone(editorials, maps_place_editorial_clone, &p->editorials);
704 }
705
706 EXPORT_API int maps_place_set_images(maps_place_h place, const maps_item_list_h images)
707 {
708         if (!maps_condition_check_maps_feature())
709                 return MAPS_ERROR_NOT_SUPPORTED;
710         if (!place || !images)
711                 return MAPS_ERROR_INVALID_PARAMETER;
712         maps_place_s *p = (maps_place_s *) place;
713         if (p->images) {
714                 maps_item_list_remove_all(p->images, maps_place_image_destroy);
715                 maps_item_list_destroy(p->images);
716         }
717         return maps_item_list_clone(images, maps_place_image_clone, &p->images);
718 }
719
720 EXPORT_API int maps_place_set_reviews(maps_place_h place, const maps_item_list_h reviews)
721 {
722         if (!maps_condition_check_maps_feature())
723                 return MAPS_ERROR_NOT_SUPPORTED;
724         if (!place || !reviews)
725                 return MAPS_ERROR_INVALID_PARAMETER;
726         maps_place_s *p = (maps_place_s *) place;
727         if (p->reviews) {
728                 maps_item_list_remove_all(p->reviews, maps_place_review_destroy);
729                 maps_item_list_destroy(p->reviews);
730         }
731         return maps_item_list_clone(reviews, maps_place_review_clone, &p->reviews);
732 }
733
734 EXPORT_API int maps_place_set_properties(maps_place_h place,
735                                                                 const maps_item_hashtable_h properties)
736 {
737         if (!maps_condition_check_maps_feature())
738                 return MAPS_ERROR_NOT_SUPPORTED;
739         if (!place || !properties)
740                 return MAPS_ERROR_INVALID_PARAMETER;
741         maps_place_s *p = (maps_place_s *) place;
742         if (p->properties)
743                 maps_item_hashtable_destroy(p->properties);
744         return maps_item_hashtable_clone(properties, &p->properties);
745 }
746
747 EXPORT_API int maps_place_set_rating(maps_place_h place, const maps_place_rating_h rating)
748 {
749         if (!maps_condition_check_maps_feature())
750                 return MAPS_ERROR_NOT_SUPPORTED;
751         if (!place || !rating)
752                 return MAPS_ERROR_INVALID_PARAMETER;
753         maps_place_s *p = (maps_place_s *) place;
754         if (p->rating)
755                 maps_place_rating_destroy(p->rating);
756         return maps_place_rating_clone(rating, &p->rating);
757 }
758
759 EXPORT_API int maps_place_set_supplier_link(maps_place_h place,
760                                                                 const maps_place_link_object_h supplier)
761 {
762         if (!maps_condition_check_maps_feature())
763                 return MAPS_ERROR_NOT_SUPPORTED;
764         if (!place || !supplier)
765                 return MAPS_ERROR_INVALID_PARAMETER;
766         maps_place_s *p = (maps_place_s *) place;
767         if (p->supplier)
768                 maps_place_link_object_destroy(p->supplier);
769         return maps_place_link_object_clone(supplier, &p->supplier);
770 }
771
772 EXPORT_API int maps_place_set_related_link(maps_place_h place,
773                                                                 const maps_place_link_object_h related)
774 {
775         if (!maps_condition_check_maps_feature())
776                 return MAPS_ERROR_NOT_SUPPORTED;
777         if (!place || !related)
778                 return MAPS_ERROR_INVALID_PARAMETER;
779         maps_place_s *p = (maps_place_s *) place;
780         if (p->related)
781                 maps_place_link_object_destroy(p->related);
782         return maps_place_link_object_clone(related, &p->related);
783 }
784
785 int _maps_place_set_supported_data(maps_place_h place,
786                                                                 const maps_int_hashtable_h supported_data)
787 {
788         if (!maps_condition_check_maps_feature())
789                 return MAPS_ERROR_NOT_SUPPORTED;
790         if (!place || !supported_data)
791                 return MAPS_ERROR_INVALID_PARAMETER;
792         maps_place_s *p = (maps_place_s *) place;
793         if (p->supported_data)
794                 maps_int_hashtable_destroy(p->supported_data);
795         return maps_int_hashtable_clone(supported_data, &p->supported_data);
796 }
797
798 EXPORT_API int maps_place_list_foreach(const maps_place_list_h place_list,
799                                                                 maps_place_cb callback, void *user_data)
800 {
801         if (!maps_condition_check_maps_feature())
802                 return MAPS_ERROR_NOT_SUPPORTED;
803         if (!place_list || !callback)
804                 return MAPS_ERROR_INVALID_PARAMETER;
805         return maps_item_list_foreach_noclone((maps_item_list_h) place_list, callback, user_data);
806 }
807
808 EXPORT_API int maps_place_list_create(maps_place_list_h *place_list)
809 {
810         if (!maps_condition_check_maps_feature())
811                 return MAPS_ERROR_NOT_SUPPORTED;
812         if (!place_list)
813                 return MAPS_ERROR_INVALID_PARAMETER;
814         return maps_item_list_create(place_list);
815 }
816
817 EXPORT_API int maps_place_list_destroy(maps_place_list_h place_list)
818 {
819         if (!maps_condition_check_maps_feature())
820                 return MAPS_ERROR_NOT_SUPPORTED;
821         if (!place_list)
822                 return MAPS_ERROR_INVALID_PARAMETER;
823
824         int error = maps_item_list_remove_all(place_list, maps_place_destroy);
825         if (error != MAPS_ERROR_NONE)
826                 return error;
827         return maps_item_list_destroy(place_list);
828 }