63c47e1c81d846d9ee37ab0cf4cf6ecac6fd9df0
[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                 MAPS_LOGE("OUT_OF_MEMORY(0x%08x)", MAPS_ERROR_OUT_OF_MEMORY);
107                 return MAPS_ERROR_OUT_OF_MEMORY;
108         }
109
110         return MAPS_ERROR_NONE;
111 }
112
113 EXPORT_API int maps_place_destroy(maps_place_h place)
114 {
115         if (!maps_condition_check_maps_feature())
116                 return MAPS_ERROR_NOT_SUPPORTED;
117         if (!place)
118                 return MAPS_ERROR_INVALID_PARAMETER;
119
120         maps_place_s *p = (maps_place_s *) place;
121
122         if (p->id)
123                 g_free(p->id);
124         if (p->name)
125                 g_free(p->name);
126         if (p->uri)
127                 g_free(p->uri);
128
129         if (p->location)
130                 maps_coordinates_destroy(p->location);
131
132         if (p->address)
133                 maps_address_destroy(p->address);
134
135         if (p->rating)
136                 maps_place_rating_destroy(p->rating);
137
138         if (p->properties)
139                 maps_item_hashtable_destroy(p->properties);
140
141         if (p->categories) {
142                 maps_item_list_remove_all(p->categories,
143                         maps_place_category_destroy);
144                 maps_item_list_destroy(p->categories);
145         }
146
147         if (p->attribute) {
148                 maps_item_list_remove_all(p->attribute,
149                         maps_place_attribute_destroy);
150                 maps_item_list_destroy(p->attribute);
151         }
152
153         if (p->contacts) {
154                 maps_item_list_remove_all(p->contacts,
155                         maps_place_contact_destroy);
156                 maps_item_list_destroy(p->contacts);
157         }
158
159         if (p->editorials) {
160                 maps_item_list_remove_all(p->editorials,
161                         maps_place_editorial_destroy);
162                 maps_item_list_destroy(p->editorials);
163         }
164
165         if (p->images) {
166                 maps_item_list_remove_all(p->images, maps_place_image_destroy);
167                 maps_item_list_destroy(p->images);
168         }
169
170         if (p->reviews) {
171                 maps_item_list_remove_all(p->reviews,
172                         maps_place_review_destroy);
173                 maps_item_list_destroy(p->reviews);
174         }
175
176         if (p->supplier)
177                 maps_place_link_object_destroy(p->supplier);
178         if (p->related)
179                 maps_place_link_object_destroy(p->related);
180
181         if (p->supported_data)
182                 maps_int_hashtable_destroy(p->supported_data);
183
184         g_slice_free(maps_place_s, place);
185         return MAPS_ERROR_NONE;
186 }
187
188 EXPORT_API int maps_place_clone(const maps_place_h origin,
189                                 maps_place_h *cloned)
190 {
191         if (!maps_condition_check_maps_feature())
192                 return MAPS_ERROR_NOT_SUPPORTED;
193         if (!cloned || !origin)
194                 return MAPS_ERROR_INVALID_PARAMETER;
195
196         int error = MAPS_ERROR_NONE;
197         do {
198                 error = maps_place_create(cloned);
199                 if (!(*cloned) || (error != MAPS_ERROR_NONE))
200                         break;
201
202                 maps_place_s *p = (maps_place_s *) origin;
203
204                 if (p->id) {
205                         error = maps_place_set_id(*cloned, p->id);
206                         if (error != MAPS_ERROR_NONE)
207                                 break;
208                 }
209
210                 if (p->name) {
211                         error = maps_place_set_name(*cloned, p->name);
212                         if (error != MAPS_ERROR_NONE)
213                                 break;
214                 }
215
216                 if (p->uri) {
217                         error = maps_place_set_uri(*cloned, p->uri);
218                         if (error != MAPS_ERROR_NONE)
219                                 break;
220                 }
221
222                 if (p->location) {
223                         error = maps_place_set_location(*cloned, p->location);
224                         if (error != MAPS_ERROR_NONE)
225                                 break;
226                 }
227
228                 error = maps_place_set_distance(*cloned, p->distance);
229                 if (error != MAPS_ERROR_NONE)
230                         break;
231
232                 if (p->address) {
233                         error = maps_place_set_address(*cloned, p->address);
234                         if (error != MAPS_ERROR_NONE)
235                                 break;
236                 }
237
238                 if (p->rating) {
239                         error = maps_place_set_rating(*cloned, p->rating);
240                         if (error != MAPS_ERROR_NONE)
241                                 break;
242                 }
243
244                 if (p->properties) {
245                         error = maps_place_set_properties(*cloned, p->properties);
246                         if (error != MAPS_ERROR_NONE)
247                                 break;
248                 }
249
250                 if (p->categories) {
251                         error = maps_place_set_categories(*cloned, p->categories);
252                         if (error != MAPS_ERROR_NONE)
253                                 break;
254                 }
255
256                 if (p->attribute) {
257                         error = maps_place_set_attributes(*cloned, p->attribute);
258                         if (error != MAPS_ERROR_NONE)
259                                 break;
260                 }
261
262                 if (p->contacts) {
263                         error = maps_place_set_contacts(*cloned, p->contacts);
264                         if (error != MAPS_ERROR_NONE)
265                                 break;
266                 }
267
268                 if (p->editorials) {
269                         error = maps_place_set_editorials(*cloned, p->editorials);
270                         if (error != MAPS_ERROR_NONE)
271                                 break;
272                 }
273
274                 if (p->images) {
275                         error = maps_place_set_images(*cloned, p->images);
276                         if (error != MAPS_ERROR_NONE)
277                                 break;
278                 }
279
280                 if (p->reviews) {
281                         error = maps_place_set_reviews(*cloned, p->reviews);
282                         if (error != MAPS_ERROR_NONE)
283                                 break;
284                 }
285
286                 if (p->supplier) {
287                         error = maps_place_set_supplier_link(*cloned, p->supplier);
288                         if (error != MAPS_ERROR_NONE)
289                                 break;
290                 }
291
292                 if (p->related) {
293                         error = maps_place_set_related_link(*cloned, p->related);
294                         if (error != MAPS_ERROR_NONE)
295                                 break;
296                 }
297
298                 if (p->supported_data) {
299                         error = _maps_place_set_supported_data(*cloned, p->supported_data);
300                         if (error != MAPS_ERROR_NONE)
301                                 break;
302                 }
303
304                 return MAPS_ERROR_NONE;
305         } while (false);
306
307         maps_place_destroy(*cloned);
308         *cloned = NULL;
309         return error;
310 }
311
312 /*----------------------------------------------------------------------------*/
313
314 EXPORT_API int maps_place_get_id(const maps_place_h place, char **id)
315 {
316         if (!maps_condition_check_maps_feature())
317                 return MAPS_ERROR_NOT_SUPPORTED;
318         if (!place || !id)
319                 return MAPS_ERROR_INVALID_PARAMETER;
320         if (!((maps_place_s *) place)->id)
321                 return MAPS_ERROR_NOT_FOUND;
322         return maps_get_string(((maps_place_s *) place)->id,
323                 _MAPS_PLACE_ID_MAX_LENGTH, id);
324 }
325
326 EXPORT_API int maps_place_get_name(const maps_place_h place, char **name)
327 {
328         if (!maps_condition_check_maps_feature())
329                 return MAPS_ERROR_NOT_SUPPORTED;
330         if (!place || !name)
331                 return MAPS_ERROR_INVALID_PARAMETER;
332         if (!((maps_place_s *) place)->name)
333                 return MAPS_ERROR_NOT_FOUND;
334         return maps_get_string(((maps_place_s *) place)->name,
335                 _MAPS_PLACE_NAME_MAX_LENGTH, name);
336 }
337
338 EXPORT_API int maps_place_get_uri(const maps_place_h place, char **uri)
339 {
340         if (!maps_condition_check_maps_feature())
341                 return MAPS_ERROR_NOT_SUPPORTED;
342         if (!place || !uri)
343                 return MAPS_ERROR_INVALID_PARAMETER;
344         if (!((maps_place_s *) place)->uri)
345                 return MAPS_ERROR_NOT_FOUND;
346         return maps_get_string(((maps_place_s *) place)->uri,
347                 _MAPS_PLACE_URI_MAX_LENGTH, uri);
348 }
349
350 EXPORT_API int maps_place_get_location(const maps_place_h place,
351                                                                 maps_coordinates_h *location)
352 {
353         if (!maps_condition_check_maps_feature())
354                 return MAPS_ERROR_NOT_SUPPORTED;
355         if (!place || !location)
356                 return MAPS_ERROR_INVALID_PARAMETER;
357         if (!((maps_place_s *) place)->location)
358                 return MAPS_ERROR_NOT_FOUND;
359         return maps_coordinates_clone(((maps_place_s *) place)->location,
360                 location);
361 }
362
363 EXPORT_API int maps_place_get_distance(const maps_place_h place, int *distance)
364 {
365         if (!maps_condition_check_maps_feature())
366                 return MAPS_ERROR_NOT_SUPPORTED;
367         if (!place || !distance)
368                 return MAPS_ERROR_INVALID_PARAMETER;
369         *distance = ((maps_place_s *) place)->distance;
370         return MAPS_ERROR_NONE;
371 }
372
373 EXPORT_API int maps_place_get_address(const maps_place_h place,
374                                                                 maps_address_h *address)
375 {
376         if (!maps_condition_check_maps_feature())
377                 return MAPS_ERROR_NOT_SUPPORTED;
378         if (!place)
379                 return MAPS_ERROR_INVALID_PARAMETER;
380         if (!__is_supported(place, MAPS_PLACE_ADDRESS))
381                 return MAPS_ERROR_NOT_SUPPORTED;
382         if (!address)
383                 return MAPS_ERROR_INVALID_PARAMETER;
384         if (!((maps_place_s *) place)->address)
385                 return MAPS_ERROR_NOT_FOUND;
386         return maps_address_clone(((maps_place_s *) place)->address, address);
387 }
388
389 EXPORT_API int maps_place_get_rating(const maps_place_h place,
390                                                                 maps_place_rating_h *rating)
391 {
392         if (!maps_condition_check_maps_feature())
393                 return MAPS_ERROR_NOT_SUPPORTED;
394         if (!place)
395                 return MAPS_ERROR_INVALID_PARAMETER;
396         if (!__is_supported(place, MAPS_PLACE_RATING))
397                 return MAPS_ERROR_NOT_SUPPORTED;
398         if (!rating)
399                 return MAPS_ERROR_INVALID_PARAMETER;
400         if (!((maps_place_s *) place)->rating)
401                 return MAPS_ERROR_NOT_FOUND;
402         return maps_place_rating_clone(((maps_place_s *) place)->rating, rating);
403 }
404
405 EXPORT_API int maps_place_foreach_property(const maps_place_h place,
406                                                                 maps_place_properties_cb callback,
407                                                                 void *user_data)
408 {
409         if (!maps_condition_check_maps_feature())
410                 return MAPS_ERROR_NOT_SUPPORTED;
411         if (!place || !callback)
412                 return MAPS_ERROR_INVALID_PARAMETER;
413         if (!((maps_place_s *) place)->properties)
414                 return MAPS_ERROR_NOT_FOUND;
415         return maps_item_hashtable_foreach(((maps_place_s *) place)->properties,
416                 callback, user_data);
417 }
418
419 EXPORT_API int maps_place_foreach_category(const maps_place_h place,
420                                                                 maps_place_categories_cb callback,
421                                                                 void *user_data)
422 {
423         if (!maps_condition_check_maps_feature())
424                 return MAPS_ERROR_NOT_SUPPORTED;
425         if (!place)
426                 return MAPS_ERROR_INVALID_PARAMETER;
427         if (!__is_supported(place, MAPS_PLACE_CATEGORIES))
428                 return MAPS_ERROR_NOT_SUPPORTED;
429         if (!callback)
430                 return MAPS_ERROR_INVALID_PARAMETER;
431         if (!((maps_place_s *) place)->categories)
432                 return MAPS_ERROR_NOT_FOUND;
433         return maps_item_list_foreach(((maps_place_s *) place)->categories,
434                 maps_place_category_clone, callback, user_data);
435 }
436
437 EXPORT_API int maps_place_foreach_attribute(const maps_place_h place,
438                                                                 maps_place_attributes_cb callback,
439                                                                 void * user_data)
440 {
441         if (!maps_condition_check_maps_feature())
442                 return MAPS_ERROR_NOT_SUPPORTED;
443         if (!place)
444                 return MAPS_ERROR_INVALID_PARAMETER;
445         if (!__is_supported(place, MAPS_PLACE_ATTRIBUTES))
446                 return MAPS_ERROR_NOT_SUPPORTED;
447         if (!callback)
448                 return MAPS_ERROR_INVALID_PARAMETER;
449         if (!((maps_place_s *) place)->attribute)
450                 return MAPS_ERROR_NOT_FOUND;
451         return maps_item_list_foreach(((maps_place_s *) place)->attribute,
452                 maps_place_attribute_clone, callback, user_data);
453 }
454
455 EXPORT_API int maps_place_foreach_contact(const maps_place_h place,
456                                                                 maps_place_contacts_cb callback,
457                                                                 void *user_data)
458 {
459         if (!maps_condition_check_maps_feature())
460                 return MAPS_ERROR_NOT_SUPPORTED;
461         if (!place)
462                 return MAPS_ERROR_INVALID_PARAMETER;
463         if (!__is_supported(place, MAPS_PLACE_CONTACTS))
464                 return MAPS_ERROR_NOT_SUPPORTED;
465         if (!callback)
466                 return MAPS_ERROR_INVALID_PARAMETER;
467         if (!((maps_place_s *) place)->contacts)
468                 return MAPS_ERROR_NOT_FOUND;
469         return maps_item_list_foreach(((maps_place_s *) place)->contacts,
470                 maps_place_contact_clone, callback, user_data);
471 }
472
473 EXPORT_API int maps_place_foreach_editorial(const maps_place_h place,
474                                                                 maps_place_editorials_cb callback,
475                                                                 void *user_data)
476 {
477         if (!maps_condition_check_maps_feature())
478                 return MAPS_ERROR_NOT_SUPPORTED;
479         if (!place)
480                 return MAPS_ERROR_INVALID_PARAMETER;
481         if (!__is_supported(place, MAPS_PLACE_EDITORIALS))
482                 return MAPS_ERROR_NOT_SUPPORTED;
483         if (!callback)
484                 return MAPS_ERROR_INVALID_PARAMETER;
485         if (!((maps_place_s *) place)->editorials)
486                 return MAPS_ERROR_NOT_FOUND;
487         return maps_item_list_foreach(((maps_place_s *) place)->editorials,
488                 maps_place_editorial_clone, callback, user_data);
489 }
490
491 EXPORT_API int maps_place_foreach_image(const maps_place_h place,
492                                                                 maps_place_images_cb callback,
493                                                                 void *user_data)
494 {
495         if (!maps_condition_check_maps_feature())
496                 return MAPS_ERROR_NOT_SUPPORTED;
497         if (!place)
498                 return MAPS_ERROR_INVALID_PARAMETER;
499         if (!__is_supported(place, MAPS_PLACE_IMAGE))
500                 return MAPS_ERROR_NOT_SUPPORTED;
501         if (!callback)
502                 return MAPS_ERROR_INVALID_PARAMETER;
503         if (!((maps_place_s *) place)->images)
504                 return MAPS_ERROR_NOT_FOUND;
505         return maps_item_list_foreach(((maps_place_s *) place)->images,
506                 maps_place_image_clone, callback, user_data);
507 }
508
509 EXPORT_API int maps_place_foreach_review(const maps_place_h place,
510                                                                 maps_place_reviews_cb callback,
511                                                                 void *user_data)
512 {
513         if (!maps_condition_check_maps_feature())
514                 return MAPS_ERROR_NOT_SUPPORTED;
515         if (!place)
516                 return MAPS_ERROR_INVALID_PARAMETER;
517         if (!__is_supported(place, MAPS_PLACE_REVIEWS))
518                 return MAPS_ERROR_NOT_SUPPORTED;
519         if (!callback)
520                 return MAPS_ERROR_INVALID_PARAMETER;
521         if (!((maps_place_s *) place)->reviews)
522                 return MAPS_ERROR_NOT_FOUND;
523         return maps_item_list_foreach(((maps_place_s *) place)->reviews,
524                 maps_place_review_clone, callback, user_data);
525 }
526
527 EXPORT_API int maps_place_get_supplier_link(const maps_place_h place,
528                                                                 maps_place_link_object_h *supplier)
529 {
530         if (!maps_condition_check_maps_feature())
531                 return MAPS_ERROR_NOT_SUPPORTED;
532         if (!place)
533                 return MAPS_ERROR_INVALID_PARAMETER;
534         if (!__is_supported(place, MAPS_PLACE_SUPPLIER))
535                 return MAPS_ERROR_NOT_SUPPORTED;
536         if (!supplier)
537                 return MAPS_ERROR_INVALID_PARAMETER;
538         if (!((maps_place_s *) place)->supplier)
539                 return MAPS_ERROR_NOT_FOUND;
540         return maps_place_link_object_clone(((maps_place_s *) place)->supplier, supplier);
541 }
542
543 EXPORT_API int maps_place_get_related_link(const maps_place_h place,
544                                                                 maps_place_link_object_h *related)
545 {
546         if (!maps_condition_check_maps_feature())
547                 return MAPS_ERROR_NOT_SUPPORTED;
548         if (!place)
549                 return MAPS_ERROR_INVALID_PARAMETER;
550         if (!__is_supported(place, MAPS_PLACE_RELATED))
551                 return MAPS_ERROR_NOT_SUPPORTED;
552         if (!related)
553                 return MAPS_ERROR_INVALID_PARAMETER;
554         if (!((maps_place_s *) place)->related)
555                 return MAPS_ERROR_NOT_FOUND;
556         return maps_place_link_object_clone(((maps_place_s *) place)->related, related);
557 }
558
559 int _maps_place_is_data_supported(const maps_place_h place,
560                                                                 maps_service_data_e data, bool *supported)
561 {
562         if (!maps_condition_check_maps_feature())
563                 return MAPS_ERROR_NOT_SUPPORTED;
564         if (!place || !supported)
565                 return MAPS_ERROR_INVALID_PARAMETER;
566
567         maps_place_s *p = (maps_place_s *)place;
568         if (!p->supported_data) {
569                 /* This is a case when the "supported" flags are not set yet */
570                 /* No need to limit access to fields */
571                 *supported = true;
572                 return MAPS_ERROR_NONE;
573         }
574
575         *supported = false;
576         return maps_int_hashtable_contains(p->supported_data, data, supported);
577 }
578
579 /*----------------------------------------------------------------------------*/
580
581 EXPORT_API int maps_place_set_id(maps_place_h place, const char *id)
582 {
583         if (!maps_condition_check_maps_feature())
584                 return MAPS_ERROR_NOT_SUPPORTED;
585         if (!place || !id)
586                 return MAPS_ERROR_INVALID_PARAMETER;
587         return maps_set_string(id, _MAPS_PLACE_ID_MAX_LENGTH,
588                 &((maps_place_s *) place)->id);
589 }
590
591 EXPORT_API int maps_place_set_name(maps_place_h place, const char *name)
592 {
593         if (!maps_condition_check_maps_feature())
594                 return MAPS_ERROR_NOT_SUPPORTED;
595         if (!place || !name)
596                 return MAPS_ERROR_INVALID_PARAMETER;
597         return maps_set_string(name, _MAPS_PLACE_NAME_MAX_LENGTH,
598                 &((maps_place_s *) place)->name);
599 }
600
601 EXPORT_API int maps_place_set_uri(maps_place_h place, const char *uri)
602 {
603         if (!maps_condition_check_maps_feature())
604                 return MAPS_ERROR_NOT_SUPPORTED;
605         if (!place || !uri)
606                 return MAPS_ERROR_INVALID_PARAMETER;
607         return maps_set_string(uri, _MAPS_PLACE_URI_MAX_LENGTH,
608                 &((maps_place_s *) place)->uri);
609 }
610
611 EXPORT_API int maps_place_set_location(maps_place_h place, const maps_coordinates_h location)
612 {
613         if (!maps_condition_check_maps_feature())
614                 return MAPS_ERROR_NOT_SUPPORTED;
615         if (!place || !location)
616                 return MAPS_ERROR_INVALID_PARAMETER;
617         maps_place_s *p = (maps_place_s *) place;
618         if (p->location)
619                 maps_coordinates_destroy(p->location);
620         return maps_coordinates_clone(location, &p->location);
621 }
622
623 EXPORT_API int maps_place_set_distance(maps_place_h place, const int distance)
624 {
625         if (!maps_condition_check_maps_feature())
626                 return MAPS_ERROR_NOT_SUPPORTED;
627         if (!place || distance < 0)
628                 return MAPS_ERROR_INVALID_PARAMETER;
629         maps_place_s *p = (maps_place_s *) place;
630         p->distance = distance;
631         return MAPS_ERROR_NONE;
632 }
633
634 EXPORT_API int maps_place_set_address(maps_place_h place, const maps_address_h address)
635 {
636         if (!maps_condition_check_maps_feature())
637                 return MAPS_ERROR_NOT_SUPPORTED;
638         if (!place || !address)
639                 return MAPS_ERROR_INVALID_PARAMETER;
640         maps_place_s *p = (maps_place_s *) place;
641         if (p->address)
642                 maps_address_destroy(p->address);
643         return maps_address_clone(address, &p->address);
644 }
645
646 EXPORT_API int maps_place_set_categories(maps_place_h place, const maps_item_list_h categories)
647 {
648         if (!maps_condition_check_maps_feature())
649                 return MAPS_ERROR_NOT_SUPPORTED;
650         if (!place || !categories)
651                 return MAPS_ERROR_INVALID_PARAMETER;
652         maps_place_s *p = (maps_place_s *) place;
653         if (p->categories) {
654                 maps_item_list_remove_all(p->categories, maps_place_category_destroy);
655                 maps_item_list_destroy(p->categories);
656         }
657         return maps_item_list_clone(categories, maps_place_category_clone, &p->categories);
658 }
659
660 EXPORT_API int maps_place_set_attributes(maps_place_h place, const maps_item_list_h attributes)
661 {
662         if (!maps_condition_check_maps_feature())
663                 return MAPS_ERROR_NOT_SUPPORTED;
664         if (!place || !attributes)
665                 return MAPS_ERROR_INVALID_PARAMETER;
666         maps_place_s *p = (maps_place_s *) place;
667         if (p->attribute) {
668                 maps_item_list_remove_all(p->attribute, maps_place_attribute_destroy);
669                 maps_item_list_destroy(p->attribute);
670         }
671         return maps_item_list_clone(attributes, maps_place_attribute_clone, &p->attribute);
672 }
673
674 EXPORT_API int maps_place_set_contacts(maps_place_h place, const maps_item_list_h contacts)
675 {
676         if (!maps_condition_check_maps_feature())
677                 return MAPS_ERROR_NOT_SUPPORTED;
678         if (!place || !contacts)
679                 return MAPS_ERROR_INVALID_PARAMETER;
680         maps_place_s *p = (maps_place_s *) place;
681         if (p->contacts) {
682                 maps_item_list_remove_all(p->contacts, maps_place_contact_destroy);
683                 maps_item_list_destroy(p->contacts);
684         }
685         return maps_item_list_clone(contacts, maps_place_contact_clone, &p->contacts);
686 }
687
688 EXPORT_API int maps_place_set_editorials(maps_place_h place, const maps_item_list_h editorials)
689 {
690         if (!maps_condition_check_maps_feature())
691                 return MAPS_ERROR_NOT_SUPPORTED;
692         if (!place || !editorials)
693                 return MAPS_ERROR_INVALID_PARAMETER;
694         maps_place_s *p = (maps_place_s *) place;
695         if (p->editorials) {
696                 maps_item_list_remove_all(p->editorials, maps_place_editorial_destroy);
697                 maps_item_list_destroy(p->editorials);
698         }
699         return maps_item_list_clone(editorials, maps_place_editorial_clone, &p->editorials);
700 }
701
702 EXPORT_API int maps_place_set_images(maps_place_h place, const maps_item_list_h images)
703 {
704         if (!maps_condition_check_maps_feature())
705                 return MAPS_ERROR_NOT_SUPPORTED;
706         if (!place || !images)
707                 return MAPS_ERROR_INVALID_PARAMETER;
708         maps_place_s *p = (maps_place_s *) place;
709         if (p->images) {
710                 maps_item_list_remove_all(p->images, maps_place_image_destroy);
711                 maps_item_list_destroy(p->images);
712         }
713         return maps_item_list_clone(images, maps_place_image_clone, &p->images);
714 }
715
716 EXPORT_API int maps_place_set_reviews(maps_place_h place, const maps_item_list_h reviews)
717 {
718         if (!maps_condition_check_maps_feature())
719                 return MAPS_ERROR_NOT_SUPPORTED;
720         if (!place || !reviews)
721                 return MAPS_ERROR_INVALID_PARAMETER;
722         maps_place_s *p = (maps_place_s *) place;
723         if (p->reviews) {
724                 maps_item_list_remove_all(p->reviews, maps_place_review_destroy);
725                 maps_item_list_destroy(p->reviews);
726         }
727         return maps_item_list_clone(reviews, maps_place_review_clone, &p->reviews);
728 }
729
730 EXPORT_API int maps_place_set_properties(maps_place_h place,
731                                                                 const maps_item_hashtable_h properties)
732 {
733         if (!maps_condition_check_maps_feature())
734                 return MAPS_ERROR_NOT_SUPPORTED;
735         if (!place || !properties)
736                 return MAPS_ERROR_INVALID_PARAMETER;
737         maps_place_s *p = (maps_place_s *) place;
738         if (p->properties)
739                 maps_item_hashtable_destroy(p->properties);
740         return maps_item_hashtable_clone(properties, &p->properties);
741 }
742
743 EXPORT_API int maps_place_set_rating(maps_place_h place, const maps_place_rating_h rating)
744 {
745         if (!maps_condition_check_maps_feature())
746                 return MAPS_ERROR_NOT_SUPPORTED;
747         if (!place || !rating)
748                 return MAPS_ERROR_INVALID_PARAMETER;
749         maps_place_s *p = (maps_place_s *) place;
750         if (p->rating)
751                 maps_place_rating_destroy(p->rating);
752         return maps_place_rating_clone(rating, &p->rating);
753 }
754
755 EXPORT_API int maps_place_set_supplier_link(maps_place_h place,
756                                                                 const maps_place_link_object_h supplier)
757 {
758         if (!maps_condition_check_maps_feature())
759                 return MAPS_ERROR_NOT_SUPPORTED;
760         if (!place || !supplier)
761                 return MAPS_ERROR_INVALID_PARAMETER;
762         maps_place_s *p = (maps_place_s *) place;
763         if (p->supplier)
764                 maps_place_link_object_destroy(p->supplier);
765         return maps_place_link_object_clone(supplier, &p->supplier);
766 }
767
768 EXPORT_API int maps_place_set_related_link(maps_place_h place,
769                                                                 const maps_place_link_object_h related)
770 {
771         if (!maps_condition_check_maps_feature())
772                 return MAPS_ERROR_NOT_SUPPORTED;
773         if (!place || !related)
774                 return MAPS_ERROR_INVALID_PARAMETER;
775         maps_place_s *p = (maps_place_s *) place;
776         if (p->related)
777                 maps_place_link_object_destroy(p->related);
778         return maps_place_link_object_clone(related, &p->related);
779 }
780
781 int _maps_place_set_supported_data(maps_place_h place,
782                                                                 const maps_int_hashtable_h supported_data)
783 {
784         if (!maps_condition_check_maps_feature())
785                 return MAPS_ERROR_NOT_SUPPORTED;
786         if (!place || !supported_data)
787                 return MAPS_ERROR_INVALID_PARAMETER;
788         maps_place_s *p = (maps_place_s *) place;
789         if (p->supported_data)
790                 maps_int_hashtable_destroy(p->supported_data);
791         return maps_int_hashtable_clone(supported_data, &p->supported_data);
792 }
793
794 EXPORT_API int maps_place_list_foreach(const maps_place_list_h place_list,
795                                                                 maps_place_cb callback, void *user_data)
796 {
797         if (!maps_condition_check_maps_feature())
798                 return MAPS_ERROR_NOT_SUPPORTED;
799         if (!place_list || !callback)
800                 return MAPS_ERROR_INVALID_PARAMETER;
801         return maps_item_list_foreach_noclone((maps_item_list_h) place_list, callback, user_data);
802 }
803
804 EXPORT_API int maps_place_list_create(maps_place_list_h *place_list)
805 {
806         if (!maps_condition_check_maps_feature())
807                 return MAPS_ERROR_NOT_SUPPORTED;
808         if (!place_list)
809                 return MAPS_ERROR_INVALID_PARAMETER;
810         return maps_item_list_create(place_list);
811 }
812
813 EXPORT_API int maps_place_list_destroy(maps_place_list_h place_list)
814 {
815         if (!maps_condition_check_maps_feature())
816                 return MAPS_ERROR_NOT_SUPPORTED;
817         if (!place_list)
818                 return MAPS_ERROR_INVALID_PARAMETER;
819
820         int error = maps_item_list_remove_all(place_list, maps_place_destroy);
821         if (error != MAPS_ERROR_NONE)
822                 return error;
823         return maps_item_list_destroy(place_list);
824 }