Fix a crash
[framework/location/libdecarta.git] / decarta / decarta_geocode.c
1 /*
2  * libdecarta
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 #include <glib.h>
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "decarta_log.h"
28 #include "decarta_config.h"
29 #include "http_wrapper.h"
30 #include "decarta_xml.h"
31 #include "decarta_geocode.h"
32
33 typedef struct {
34         DecartaGeocodeCB callback;
35         DecartaHandle *handle;
36         void* userdata;
37 } GeocodeCBData;
38
39 typedef struct {
40         DecartaReverseGeocodeCB callback;
41         DecartaHandle *handle;
42         void* userdata;
43 } ReverseGeocodeCBData;
44
45 struct _DecartaHandle {
46         HttpHandle      http_async_geo;
47         HttpHandle      http_async_rev_geo;
48 };
49
50 static void
51 search_reverse_geocode_cb (gboolean success,
52         char *recv_data,
53         void *userdata)
54 {
55         DECARTA_LOGD("search_reverse_geocode_cb");
56     ReverseGeocodeCBData* cb_data = (ReverseGeocodeCBData*)userdata;
57     DecartaError err = DECARTA_ERROR_NONE;
58     DecartaGeocode *geocode = NULL;
59         if (success != TRUE) err = DECARTA_ERROR_HTTP;
60         else if (!xml_reverse_geocode_parse(recv_data, &geocode)) err = DECARTA_ERROR_XML;
61         if (cb_data->callback) cb_data->callback (err, geocode, cb_data->userdata);
62         g_free(recv_data);
63         if (cb_data->handle) {
64                 g_free(cb_data->handle);
65                 cb_data->handle = NULL;
66         }
67         if (geocode) decarta_geocode_free (geocode);
68         g_free(cb_data);
69 }
70
71 static void
72 search_geocode_cb (gboolean success,
73         char *recv_data,
74         void *userdata)
75 {
76         DECARTA_LOGD("search_geocode_cb");
77     GeocodeCBData* cb_data = (GeocodeCBData*)userdata;
78     DecartaError err = DECARTA_ERROR_NONE;
79     GList *geocode_ist = NULL;
80         if (success != TRUE) err = DECARTA_ERROR_HTTP;
81         else if (!xml_geocode_parse(recv_data, &geocode_ist)) err = DECARTA_ERROR_XML;
82         if (cb_data->callback) cb_data->callback (err, geocode_ist, cb_data->userdata);
83         g_free(recv_data);
84         if (cb_data->handle) {
85                 g_free(cb_data->handle);
86                 cb_data->handle = NULL;
87         }
88         if (geocode_ist) decarta_geocode_list_free (geocode_ist);
89         g_free(cb_data);
90 }
91
92 EXPORT_API int
93 decarta_search_reverse_geocode (const DecartaPosition *pos,
94         DecartaGeocode **geocode)
95 {
96         DECARTA_LOGD("decarta_search_reverse_geocode");
97         if (!pos || !geocode)   return DECARTA_ERROR_PARAMETER;
98         if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE;
99
100         int err = DECARTA_ERROR_NONE;
101         char *req = NULL;
102         char *resp = NULL;
103         unsigned int size = 0;
104         if(!xml_reverse_geocode_request_get(pos, &req, &size)) return DECARTA_ERROR_PARAMETER;
105         HttpHandle http = http_open(HTTP_TYPE_SYNC);
106         if (http_send(http, req, get_host(), &resp, NULL, NULL)) {
107                 if (!xml_reverse_geocode_parse(resp, geocode)) err = DECARTA_ERROR_XML;
108         } else err = DECARTA_ERROR_HTTP;
109         g_free (req);
110         g_free (resp);
111         http_close(http);
112         return err;
113 }
114
115 EXPORT_API int
116 decarta_search_geocode (const DecartaAddress *address,
117         GList **geocode_list)
118 {
119         DECARTA_LOGD("decarta_search_geocode");
120         if (!address || !geocode_list)   return DECARTA_ERROR_PARAMETER;
121         if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE;
122
123         int err = DECARTA_ERROR_NONE;
124         char *req = NULL;
125         char *resp = NULL;
126         unsigned int size = 0;
127         if(!xml_geocode_request_get(address, &req, &size)) return DECARTA_ERROR_PARAMETER;
128         HttpHandle http = http_open(HTTP_TYPE_SYNC);
129         if (http_send(http, req, get_host(), &resp, NULL, NULL)) {
130                 if (!xml_geocode_parse(resp, geocode_list)) err = DECARTA_ERROR_XML;
131         } else err = DECARTA_ERROR_HTTP;
132         g_free (req);
133         g_free (resp);
134         http_close(http);
135         return err;
136 }
137
138 EXPORT_API int
139 decarta_search_reverse_geocode_async (const DecartaPosition *pos,
140         DecartaReverseGeocodeCB callback,
141         void *userdata,
142         DecartaHandle **handle)
143 {
144         DECARTA_LOGD("decarta_search_reverse_geocode_async");
145         if (!pos || !callback) return DECARTA_ERROR_PARAMETER;
146         if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE;
147
148         *handle = NULL;
149         char* req = NULL;
150         unsigned int size = 0;
151         ReverseGeocodeCBData* cb_data = g_new0(ReverseGeocodeCBData, 1);
152         cb_data->callback = callback;
153         cb_data->userdata = userdata;
154     if(!xml_reverse_geocode_request_get(pos, &req, &size)) {
155         g_free(cb_data);
156         return DECARTA_ERROR_PARAMETER;
157     }
158     *handle = g_new0(DecartaHandle, 1);
159     (*handle)->http_async_rev_geo = http_open(HTTP_TYPE_ASYNC);
160     cb_data->handle = *handle;
161     if(!http_send((*handle)->http_async_rev_geo, req, get_host(), NULL, (HttpCallback)search_reverse_geocode_cb, cb_data)){
162         http_close((*handle)->http_async_rev_geo);
163         g_free(*handle);
164         *handle = NULL;
165         return DECARTA_ERROR_HTTP;
166     }
167     g_free(req);
168
169     return DECARTA_ERROR_NONE;
170 }
171
172 EXPORT_API int
173 decarta_search_geocode_async (const DecartaAddress *addr,
174         DecartaGeocodeCB callback,
175         void *userdata,
176         DecartaHandle **handle)
177 {
178         DECARTA_LOGD("decarta_search_geocode_async");
179         if (!addr || !callback) return DECARTA_ERROR_PARAMETER;
180         if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE;
181
182         *handle = NULL;
183         char* req = NULL;
184         unsigned int size = 0;
185         GeocodeCBData* cb_data = g_new0(GeocodeCBData, 1);
186         cb_data->callback = callback;
187         cb_data->userdata = userdata;
188     if(!xml_geocode_request_get(addr, &req, &size)) {
189         g_free(cb_data);
190         return DECARTA_ERROR_PARAMETER;
191     }
192     *handle = g_new0(DecartaHandle, 1);
193     (*handle)->http_async_geo = http_open(HTTP_TYPE_ASYNC);
194     cb_data->handle = *handle;
195     if(!http_send((*handle)->http_async_geo, req, get_host(), NULL, (HttpCallback)search_geocode_cb, cb_data)){
196         http_close((*handle)->http_async_geo);
197         g_free(*handle);
198         *handle = NULL;
199         return DECARTA_ERROR_HTTP;
200     }
201     g_free(req);
202
203     return DECARTA_ERROR_NONE;
204 }
205
206 EXPORT_API void
207 decarta_search_geocode_async_cancel (DecartaHandle *handle)
208 {
209         DECARTA_LOGD("decarta_search_geocode_async_cancel");
210         if (handle == NULL) return;
211         if (handle->http_async_geo) {
212                 http_close (handle->http_async_geo);
213                 handle->http_async_geo = NULL;
214         }
215 }
216
217 EXPORT_API void
218 decarta_search_reverse_geocode_async_cancel (DecartaHandle *handle)
219 {
220         DECARTA_LOGD("decarta_search_reverse_geocode_async_cancel");
221         if (handle == NULL) return;
222         if (handle->http_async_rev_geo) {
223                 http_close (handle->http_async_rev_geo);
224                 handle->http_async_rev_geo = NULL;
225         }
226 }