Fixed svace defects
[platform/core/location/maps-plugin-mapquest.git] / src / mapquest / mapquest_jsonparser.c
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18 #include <json-glib/json-glib.h>
19 #include "mapquest_jsonparser.h"
20 #include "mapquest_queue.h"
21 #include "mapquest_debug.h"
22 #include "mapquest_util.h"
23
24 #define ROUTE_UNIT_CONVERSION_MILE_TO_M(x)      (1609.34 * (x))
25 #define ROUTE_UNIT_CONVERSION_MILE_TO_KM(x)     (1.60934 * (x))
26 #define ROUTE_UNIT_CONVERSION_MILE_TO_FT(x)     (5280 * (x))
27 #define ROUTE_UNIT_CONVERSION_MILE_TO_YD(x)     (1760 * (x))
28
29 static route_unit __route_unit = ROUTE_UNIT_M;
30 static int __maneuver_index = 0;
31 static coords_s __destination_point;
32
33 static mapquest_error_e __convert_status(int status)
34 {
35         mapquest_error_e error = MAPQUEST_ERROR_UNKNOWN;
36         switch (status) {
37         case 0:
38                 {
39                         /* Successful Geocode call */
40                         error = MAPQUEST_ERROR_NONE;
41                         break;
42                 }
43         case 400:
44                 {
45                         /* Error with input - Illegal argument from request */
46                         error = MAPQUEST_ERROR_INVALID_PARAMETER;
47                         break;
48                 }
49         case 403:
50                 {
51                         /* Key related error - Invalid key */
52                         error = MAPQUEST_ERROR_KEY_NOT_AVAILABLE;
53                         break;
54                 }
55         case 500:
56                 {
57                         /* Unknown error */
58                         error = MAPQUEST_ERROR_UNKNOWN;
59                         break;
60                 }
61         case -1:
62                 {
63                         /* Network error */
64                         error = MAPQUEST_ERROR_NETWORK_UNREACHABLE;
65                         break;
66                 }
67         }
68
69         return error;
70 }
71
72 /************ GEOCODE ***************/
73
74 static void __parse_lat_lng(JsonNode *node, GList **coordsList)
75 {
76         if (!node || !coordsList) return;
77
78         gdouble latitude = 0.0;
79         gdouble longitude = 0.0;
80         JsonObject *resultObj = json_node_get_object(node);
81
82         if (resultObj) {
83                 JsonNode *latNode = json_object_get_member(resultObj, "lat");
84
85                 if (latNode) {
86                         latitude = json_node_get_double(latNode);
87                         MAP_DEBUG("Latitude :: >>> %f", latitude);
88                 }
89
90                 JsonNode *lngNode = json_object_get_member(resultObj, "lng");
91
92                 if (lngNode) {
93                         longitude = json_node_get_double(lngNode);
94                         MAP_DEBUG("Longitude :: >>> %f", longitude);
95                 }
96
97                 coords_s *coords = (coords_s *)g_malloc0(sizeof(coords_s));
98                 if (coords != NULL) {
99                         MAP_DEBUG("Storing the latitude and longitude data..");
100                         coords->latitude = latitude;
101                         coords->longitude = longitude;
102                 }
103
104                 if (*coordsList == NULL)
105                         *coordsList = g_list_append(*coordsList, coords);
106                 else
107                         *coordsList = g_list_insert_before(*coordsList, NULL, coords);
108         }
109 }
110
111 static void __parse_locations(JsonNode *node, GList **coordsList)
112 {
113         if (!node || !coordsList) return;
114
115         JsonArray *resultArray = json_node_get_array(node);
116
117         int length = json_array_get_length(resultArray);
118
119         int index = 0;
120         for (index = 0; index < length; index++) {
121
122                 JsonObject *obj = json_array_get_object_element(resultArray, index);
123
124                 if (obj) {
125                         JsonNode *latLngNode = json_object_get_member(obj, "latLng");
126
127                         if (latLngNode)
128                                 __parse_lat_lng(latLngNode, coordsList);
129                 }
130         }
131 }
132
133 static void __parse_geocode_response(char *response, int size, int *status, GList **coordsList)
134 {
135         if (!response || !status || !coordsList) return;
136
137         *coordsList = NULL;
138
139         JsonParser *parser = NULL;
140         JsonNode *root = NULL;
141         JsonNode *node = NULL;
142         JsonObject *object = NULL;
143         GError *error = NULL;
144         char data[size + 1];
145
146         parser = json_parser_new();
147
148         strncpy(data, response, size);
149         data[size] = '\0';
150
151         if (!json_parser_load_from_data(parser, data, -1, &error)) {
152                 MAP_DEBUG("Error in file parsing JSON..");
153                 g_error_free(error);
154                 g_object_unref(parser);
155                 return;
156         }
157
158         root = json_parser_get_root(parser);
159
160         object = json_node_get_object(root);
161
162         node = json_object_get_member(object, "info");
163         JsonObject *infoObj = json_node_get_object(node);
164         if (infoObj) {
165                 JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
166
167                 if (statusNode) {
168                         *status = json_node_get_int(statusNode);
169                         MAP_DEBUG("status :: >>> %d", *status);
170                 }
171         }
172
173         if (*status != 0) {     /* SUCCESS */
174                 *coordsList = NULL;
175                 return;
176         }
177
178         node = json_object_get_member(object, "results");
179         JsonArray *resultArray = json_node_get_array(node);
180
181         int length = json_array_get_length(resultArray);
182
183         int index = 0;
184         for (index = 0; index < length; index++) {
185
186                 JsonObject *obj = json_array_get_object_element(resultArray, index);
187
188                 if (obj) {
189                         JsonNode *locNode = json_object_get_member(obj, "locations");
190
191                         if (locNode)
192                                 __parse_locations(locNode, coordsList);
193                 }
194         }
195
196         g_object_unref(parser);
197 }
198
199 /****************** REVERSE GEOCODE *********************/
200
201 static void __parse_revgeocode_address(JsonNode *node, mapquest_address_resp_s **respAddr)
202 {
203         if (!node || !respAddr) return;
204
205         char *streetAddr = NULL;
206         char *neighbourhood = NULL;
207         char *city = NULL;
208         char *county =  NULL;
209         char *state = NULL;
210         char *country = NULL;
211         char *postalCode = NULL;
212
213         JsonArray *resultArray = json_node_get_array(node);
214
215         int length = json_array_get_length(resultArray);
216
217         int index = 0;
218         for (index = 0; index < length; index++) {
219
220                 JsonObject *obj = json_array_get_object_element(resultArray, index);
221
222                 if (obj) {
223                         JsonNode *tmp = NULL;
224
225                         /* Street */
226                         tmp = json_object_get_member(obj, "street");
227                         if (tmp) {
228                                 streetAddr = (char *) json_node_get_string(tmp);
229                                 if (streetAddr && strlen(streetAddr) <= 0)
230                                         streetAddr = NULL;
231                         } else {
232                                 streetAddr = NULL;
233                         }
234
235                         /* Neighborhood */
236                         tmp = json_object_get_member(obj, "adminArea6");
237                         if (tmp) {
238                                 neighbourhood = (char *) json_node_get_string(tmp);
239                                 if (neighbourhood && strlen(neighbourhood) <= 0)
240                                         neighbourhood = NULL;
241                         } else {
242                                 neighbourhood = NULL;
243                         }
244
245                         /* City */
246                         tmp = json_object_get_member(obj, "adminArea5");
247                         if (tmp) {
248                                 city = (char *) json_node_get_string(tmp);
249                                 if (city && strlen(city) <= 0)
250                                         city = NULL;
251                         } else {
252                                 city = NULL;
253                         }
254
255                         /* State */
256                         tmp = json_object_get_member(obj, "adminArea3");
257                         if (tmp) {
258                                 state = (char *) json_node_get_string(tmp);
259                                 if (state && strlen(state) <= 0)
260                                         state = NULL;
261                         } else {
262                                 state = NULL;
263                         }
264
265                         /* County */
266                         tmp = json_object_get_member(obj, "adminArea4");
267                         if (tmp) {
268                                 county = (char *) json_node_get_string(tmp);
269                                 if (county && strlen(county) <= 0)
270                                         county = NULL;
271                         } else {
272                                 county = NULL;
273                         }
274
275                         /* Country */
276                         tmp = json_object_get_member(obj, "adminArea1");
277                         if (tmp) {
278                                 country = (char *) json_node_get_string(tmp);
279                                 if (country && strlen(country) <= 0)
280                                         country = NULL;
281                         } else {
282                                 country = NULL;
283                         }
284
285                         /* Postal Code */
286                         tmp = json_object_get_member(obj, "postalCode");
287                         if (tmp) {
288                                 postalCode = (char *) json_node_get_string(tmp);
289                                 if (postalCode && strlen(postalCode) <= 0)
290                                         postalCode = NULL;
291                         } else {
292                                 postalCode = NULL;
293                         }
294
295                         if (!streetAddr && !neighbourhood && !city && !state && !county && !country && !postalCode)
296                                 continue;
297
298                         *respAddr = (mapquest_address_resp_s *)g_malloc(sizeof(mapquest_address_resp_s));
299
300                         if (*respAddr != NULL) {
301                                 /* Street Address */
302                                 if (streetAddr != NULL) {
303                                         (*respAddr)->street_add = (gchar *)g_malloc(strlen((char *)streetAddr) + 1);
304                                         STRCPY((*respAddr)->street_add, (char *) streetAddr);
305                                 } else {
306                                         MAP_DEBUG("street is NULL");
307                                         (*respAddr)->street_add = NULL;
308                                 }
309
310                                 /* Neighbourhood */
311                                 if (neighbourhood != NULL) {
312                                         (*respAddr)->neighbourhood =    (gchar *)g_malloc(strlen((char *)neighbourhood) + 1);
313                                         STRCPY((*respAddr)->neighbourhood, (char *) neighbourhood);
314                                 } else {
315                                         MAP_DEBUG("neighbourhood is NULL");
316                                         (*respAddr)->neighbourhood = NULL;
317                                 }
318
319                                 /* City */
320                                 if (city != NULL) {
321                                         (*respAddr)->city = (gchar *)g_malloc(strlen((char *)city) + 1);
322                                         STRCPY((*respAddr)->city, (char *) city);
323                                 } else {
324                                         MAP_DEBUG("city is NULL");
325                                         (*respAddr)->city = NULL;
326                                 }
327
328                                 /* County */
329                                 if (county != NULL) {
330                                         (*respAddr)->county = (gchar *)g_malloc(strlen((char *)county) + 1);
331                                         STRCPY((*respAddr)->county, (char *) county);
332                                 } else {
333                                         MAP_DEBUG("county is NULL");
334                                         (*respAddr)->county = NULL;
335                                 }
336
337                                 /* State */
338                                 if (state != NULL) {
339                                         (*respAddr)->state = (gchar *)g_malloc(strlen((char *)state) + 1);
340                                         STRCPY((*respAddr)->state, (char *) state);
341                                 } else {
342                                         MAP_DEBUG("state is NULL");
343                                         (*respAddr)->state = NULL;
344                                 }
345
346                                 /* Country */
347                                 if (country != NULL) {
348                                         (*respAddr)->country = (gchar *)g_malloc(strlen((char *)country) + 1);
349                                         STRCPY((*respAddr)->country, (char *) country);
350                                 } else {
351                                         MAP_DEBUG("country is NULL");
352                                         (*respAddr)->country = NULL;
353                                 }
354
355                                 /* Country code */
356                                 MAP_DEBUG("country code is NULL");
357                                 (*respAddr)->country_code = NULL;
358
359                                 /* Postal Code */
360                                 if (postalCode != NULL) {
361                                         (*respAddr)->postal_code = (gchar *)g_malloc(strlen((char *)postalCode) + 1);
362                                         STRCPY((*respAddr)->postal_code, (char *) postalCode);
363                                 } else {
364                                         MAP_DEBUG("postal_code is NULL");
365                                         (*respAddr)->postal_code = NULL;
366                                 }
367                         }
368                 }
369         }
370 }
371
372 static void __parse_revgeocode_response(char *response, int size, int *status, mapquest_address_resp_s **respAddr)
373 {
374         if (!response || !status || !respAddr) return;
375
376         *respAddr = NULL;
377
378         JsonParser *parser;
379         JsonNode *root;
380         JsonNode *node;
381         JsonObject *object;
382         GError *error = NULL;
383         char data[size + 1];
384
385         parser = json_parser_new();
386
387         strncpy(data, response, size);
388         data[size] = '\0';
389
390         if (!json_parser_load_from_data(parser, data, -1, &error)) {
391                 MAP_DEBUG("Error in file parsing JSON..");
392                 g_error_free(error);
393                 g_object_unref(parser);
394                 return;
395         }
396
397         root = json_parser_get_root(parser);
398
399         object = json_node_get_object(root);
400
401         node = json_object_get_member(object, "info");
402         JsonObject *infoObj = json_node_get_object(node);
403         if (infoObj) {
404                 JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
405
406                 if (statusNode) {
407                         *status = json_node_get_int(statusNode);
408                         MAP_DEBUG("status :: >>> %d", *status);
409                 }
410         }
411
412         if (*status != 0) {     /* SUCCESS */
413                 *respAddr = NULL;
414                 return;
415         }
416
417         node = json_object_get_member(object, "results");
418         JsonArray *resultArray = json_node_get_array(node);
419
420         int length = json_array_get_length(resultArray);
421
422         int index = 0;
423         for (index = 0; index < length; index++) {
424
425                 JsonObject *obj = json_array_get_object_element(resultArray, index);
426
427                 if (obj) {
428                         JsonNode *locNode = json_object_get_member(obj, "locations");
429
430                         if (locNode)
431                                 __parse_revgeocode_address(locNode, respAddr);
432                 }
433         }
434
435         g_object_unref(parser);
436 }
437
438 /****************  PLACE SEARCH ********************/
439
440 static void __place_address_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
441 {
442         if (!object || !member_name || !member_node || !user_data) return;
443
444         mapquest_address_resp_s **respAddr = (mapquest_address_resp_s **) user_data;
445
446         if (*respAddr) {
447                 JsonNode *tmp = json_object_get_member(object, member_name);
448
449                 if (!strcmp(member_name, "road"))
450                         (*respAddr)->street_add = (char *) json_node_dup_string(tmp);
451                 else if (!strcmp(member_name, "neighbourhood"))
452                         (*respAddr)->neighbourhood = (char *) json_node_dup_string(tmp);
453                 else if (!strcmp(member_name, "house_number"))
454                         (*respAddr)->building_number = (char *) json_node_dup_string(tmp);
455                 else if (!strcmp(member_name, "city"))
456                         (*respAddr)->city = (char *) json_node_dup_string(tmp);
457                 else if (!strcmp(member_name, "county"))
458                         (*respAddr)->county = (char *) json_node_dup_string(tmp);
459                 else if (!strcmp(member_name, "state"))
460                         (*respAddr)->state = (char *) json_node_dup_string(tmp);
461                 else if (!strcmp(member_name, "country"))
462                         (*respAddr)->country = (char *) json_node_dup_string(tmp);
463                 else if (!strcmp(member_name, "country_code"))
464                         (*respAddr)->country_code = (char *) json_node_dup_string(tmp);
465                 else if (!strcmp(member_name, "postcode"))
466                         (*respAddr)->postal_code = (char *) json_node_dup_string(tmp);
467         } else {
468                 *respAddr = NULL;
469         }
470 }
471
472 static void __place_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
473 {
474         if (!object || !member_name || !member_node || !user_data) return;
475
476         mapquest_place_resp_s **respPlaces = (mapquest_place_resp_s **) user_data;
477
478         JsonNode *tmp = json_object_get_member(object, member_name);
479         char *str;
480
481         if (!strcmp(member_name, "place_id")) {
482                 (*respPlaces)->place_id = (char *) json_node_get_string(tmp);
483         } else if (!strcmp(member_name, "lat")) {
484                 str = (char *) json_node_get_string(tmp);
485                 ((*respPlaces)->coordinates).latitude = (str ? atof(str) : 0);
486         } else if (!strcmp(member_name, "lon")) {
487                 str = (char *) json_node_get_string(tmp);
488                 ((*respPlaces)->coordinates).longitude = (str ? atof(str) : 0);
489         } else if (!strcmp(member_name, "class")) {
490                 (*respPlaces)->category = (char *) json_node_dup_string(tmp);
491         } else if (!strcmp(member_name, "type")) {
492                 (*respPlaces)->subcategory = (char *) json_node_dup_string(tmp);
493         } else if (!strcmp(member_name, "display_name")) {
494                 (*respPlaces)->display_name = (char *) json_node_dup_string(tmp);
495         } else if (!strcmp(member_name, "address")) {
496                 JsonObject *obj = json_node_get_object(member_node);
497
498                 (*respPlaces)->address = (mapquest_address_resp_s *)g_malloc(sizeof(mapquest_address_resp_s));
499                 if ((*respPlaces)->address) {
500                         (*respPlaces)->address->street_add = NULL;
501                         (*respPlaces)->address->neighbourhood = NULL;
502                         (*respPlaces)->address->building_number = NULL;
503                         (*respPlaces)->address->city = NULL;
504                         (*respPlaces)->address->county = NULL;
505                         (*respPlaces)->address->state = NULL;
506                         (*respPlaces)->address->country = NULL;
507                         (*respPlaces)->address->country_code = NULL;
508                         (*respPlaces)->address->postal_code = NULL;
509                 }
510
511                 json_object_foreach_member(obj, __place_address_foreach, &((*respPlaces)->address));
512         } else if (!strcmp(member_name, "icon")) {
513                 (*respPlaces)->icon_url = (char *) json_node_get_string(tmp);
514         }
515 }
516
517 static void __parse_place_response(char *response, int size, GList **placeList)
518 {
519         if (!response || !placeList) return;
520
521         *placeList = NULL;
522
523         JsonParser *parser;
524         JsonNode *root;
525         GError *error = NULL;
526         char data[size + 1];
527
528         parser = json_parser_new();
529         if (!parser) return;
530
531         strncpy(data, response, size);
532         data[size] = '\0';
533
534         if (!json_parser_load_from_data(parser, data, -1, &error)) {
535                 MAP_DEBUG("Error in file parsing JSON..");
536                 g_error_free(error);
537                 g_object_unref(parser);
538                 return;
539         }
540
541         root = json_parser_get_root(parser);
542
543         JsonArray *placeArray = json_node_get_array(root);
544
545         int length = json_array_get_length(placeArray);
546         MAP_DEBUG("Places result count :: %d", length);
547
548         int index = 0;
549         for (index = 0; index < length; index++) {
550
551                 JsonObject *obj = json_array_get_object_element(placeArray, index);
552
553                 if (obj) {
554                         mapquest_place_resp_s *respPlaces = (mapquest_place_resp_s *)g_malloc(sizeof(mapquest_place_resp_s));
555
556                         if (respPlaces) {
557                                 respPlaces->place_id = NULL;
558                                 respPlaces->category = NULL;
559                                 respPlaces->subcategory = NULL;
560                                 respPlaces->display_name = NULL;
561                                 respPlaces->address = NULL;
562                                 respPlaces->icon_url = NULL;
563
564                                 json_object_foreach_member(obj, __place_foreach, &respPlaces);
565
566                                 if (*placeList == NULL)
567                                         *placeList = g_list_append(*placeList, respPlaces);
568                                 else
569                                         *placeList = g_list_insert_before(*placeList, NULL, respPlaces);
570                         }
571                 }
572         }
573
574         g_object_unref(parser);
575 }
576
577 /********************* ROUTE RESPONSE ***********************/
578
579 static double __convert_distance_unit(double distance)
580 {
581         double val = 0.0;
582         switch (__route_unit) {
583         case ROUTE_UNIT_M:
584                 val = ROUTE_UNIT_CONVERSION_MILE_TO_M(distance);
585                 break;
586         case ROUTE_UNIT_KM:
587                 val = ROUTE_UNIT_CONVERSION_MILE_TO_KM(distance);
588                 break;
589         case ROUTE_UNIT_FT:
590                 val = ROUTE_UNIT_CONVERSION_MILE_TO_FT(distance);
591                 break;
592         case ROUTE_UNIT_YD:
593                 val = ROUTE_UNIT_CONVERSION_MILE_TO_YD(distance);
594                 break;
595         }
596
597         return val;
598 }
599
600 static void __maneuver_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
601 {
602         if (!object || !member_name || !member_node || !user_data) return;
603
604         mapquest_route_maneuver **maneuver = (mapquest_route_maneuver **) user_data;
605
606         JsonNode *tmp = json_object_get_member(object, member_name);
607
608         if (!strcmp(member_name, "startPoint")) {
609                 JsonObject *coordsObj = json_node_get_object(tmp);
610
611                 if (coordsObj) {
612                         double latitude = 0.0;
613                         double longitude = 0.0;
614                         JsonNode *latNode = json_object_get_member(coordsObj, "lat");
615
616                         if (latNode)
617                                 latitude = json_node_get_double(latNode);
618
619                         JsonNode *lngNode = json_object_get_member(coordsObj, "lng");
620
621                         if (lngNode)
622                                 longitude = json_node_get_double(lngNode);
623
624                         coords_s start_point;
625                         start_point.latitude = latitude;
626                         start_point.longitude = longitude;
627
628                         (*maneuver)->start_point = start_point;
629                 }
630         } else if (!strcmp(member_name, "narrative")) {
631                 (*maneuver)->instruction = (char *) json_node_dup_string(tmp);
632         } else if (!strcmp(member_name, "distance")) {
633                 double dist = json_node_get_double(tmp);
634                 (*maneuver)->distance = __convert_distance_unit(dist);
635         } else if (!strcmp(member_name, "time")) {
636                 (*maneuver)->time = json_node_get_int(tmp);
637         } else if (!strcmp(member_name, "formattedTime")) {
638                 (*maneuver)->formatted_time = (char *) json_node_dup_string(tmp);
639         } else if (!strcmp(member_name, "attributes")) {
640                 (*maneuver)->attribute = json_node_get_int(tmp);
641         } else if (!strcmp(member_name, "turnType")) {
642                 (*maneuver)->turn_type = json_node_get_int(tmp);
643         } else if (!strcmp(member_name, "direction")) {
644                 (*maneuver)->direction = json_node_get_int(tmp);
645         } else if (!strcmp(member_name, "directionName")) {
646                 (*maneuver)->direction_name = (char *) json_node_dup_string(tmp);
647         } else if (!strcmp(member_name, "index")) {
648                 (*maneuver)->index = json_node_get_int(tmp);
649         } else if (!strcmp(member_name, "streets")) {
650                 JsonArray *streetsArray = json_node_get_array(tmp);
651
652                 int length = json_array_get_length(streetsArray);
653
654                 char street_name[512];
655                 STRCPY(street_name, "");
656                 int index = 0;
657                 for (index = 0; index < length; index++) {
658                         char *name = (char *) json_array_get_string_element(streetsArray, index);
659                         if (name) {
660                                 if (index == 0) {
661                                         strncpy(street_name, name, sizeof(street_name)-1);
662                                 } else {
663                                         STRCAT(street_name, "/");
664                                         strncat(street_name, name, sizeof(street_name)-strlen(street_name)-1);
665                                 }
666                         }
667                 }
668
669                 if (strlen(street_name) > 0) {
670                         (*maneuver)->street_name = (gchar *)g_malloc0((strlen((char *)street_name)) + 1);
671                         if ((*maneuver)->street_name)
672                                 STRCPY((*maneuver)->street_name, (char *) street_name);
673                 } else {
674                         (*maneuver)->street_name = NULL;
675                 }
676         }
677 }
678
679 static void __parse_maneuvers(JsonNode *node, mapquest_route_resp_s **routeResp)
680 {
681         if (!node || !routeResp) return;
682
683         JsonArray *resultArray = json_node_get_array(node);
684
685         int length = json_array_get_length(resultArray);
686
687         int index = 0;
688         for (index = 0; index < length; index++) {
689
690                 JsonObject *obj = json_array_get_object_element(resultArray, index);
691
692                 if (obj) {
693                         mapquest_route_maneuver *maneuver = (mapquest_route_maneuver *)g_malloc(sizeof(mapquest_route_maneuver));
694
695                         if (maneuver) {
696                                 json_object_foreach_member(obj, __maneuver_foreach, &maneuver);
697
698                                 if (__maneuver_index != 0) {
699                                         if (maneuver->distance == 0.0 && maneuver->time == 0) {
700                                                 maneuver->start_point = __destination_point;
701                                                 maneuver->end_point = __destination_point;
702                                         } else {
703
704                                         }
705
706                                         GList *list = NULL;
707                                         list = g_list_last((*routeResp)->maneuvers);
708                                         if (list) {
709                                                 mapquest_route_maneuver *tmp = (mapquest_route_maneuver *)list->data;
710                                                 tmp->end_point = maneuver->start_point;
711                                         }
712                                 }
713
714                                 if ((*routeResp)->maneuvers == NULL)
715                                         (*routeResp)->maneuvers = g_list_append((*routeResp)->maneuvers, (gpointer)maneuver);
716                                 else
717                                         (*routeResp)->maneuvers = g_list_insert_before((*routeResp)->maneuvers, NULL, (gpointer)maneuver);
718                         }
719                         __maneuver_index++;
720                 }
721         }
722 }
723
724 static void __shape_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
725 {
726         if (!object || !member_name || !member_node || !user_data) return;
727
728         mapquest_route_resp_s **routeResp = (mapquest_route_resp_s **) user_data;
729
730         JsonNode *tmp = json_object_get_member(object, member_name);
731
732         if (!strcmp(member_name, "shapePoints")) {
733                 JsonArray *shapePointsArray = json_node_get_array(tmp);
734
735                 int length = json_array_get_length(shapePointsArray);
736
737                 int index = 0;
738                 double val = 0.0;
739                 coords_s *coords = NULL;
740                 for (index = 0; index < length; index++) {
741
742                         val = (double) json_array_get_double_element(shapePointsArray, index);
743
744                         if ((index % 2) == 0) {
745                                 /* Lat */
746                                 coords = (coords_s *)g_malloc0(sizeof(coords_s));
747                                 if (coords)
748                                         coords->latitude = val;
749                         } else {
750                                 /* Lon */
751                                 if (coords) {
752                                         coords->longitude = val;
753                                         if ((*routeResp)->shapePoints == NULL)
754                                                 (*routeResp)->shapePoints = g_list_append((*routeResp)->shapePoints, (gpointer)coords);
755                                         else
756                                                 (*routeResp)->shapePoints = g_list_insert_before((*routeResp)->shapePoints, NULL, (gpointer)coords);
757                                 }
758                         }
759                 }
760         }
761
762 }
763
764 static void __bbox_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
765 {
766         if (!object || !member_name || !member_node || !user_data) return;
767
768         mapquest_route_resp_s **routeResp = (mapquest_route_resp_s **) user_data;
769
770         JsonNode *tmp = json_object_get_member(object, member_name);
771
772         JsonObject *coordsObj = json_node_get_object(tmp);
773         double latitude = 0.0;
774         double longitude = 0.0;
775
776         if (coordsObj) {
777                 JsonNode *latNode = json_object_get_member(coordsObj, "lat");
778
779                 if (latNode)
780                         latitude = json_node_get_double(latNode);
781
782                 JsonNode *lngNode = json_object_get_member(coordsObj, "lng");
783
784                 if (lngNode)
785                         longitude = json_node_get_double(lngNode);
786         }
787
788         if (!strcmp(member_name, "ul")) {
789                 ((*routeResp)->bounding_box).top_left.latitude = latitude;
790                 ((*routeResp)->bounding_box).top_left.longitude = longitude;
791         } else if (!strcmp(member_name, "lr")) {
792                 ((*routeResp)->bounding_box).bottom_right.latitude = latitude;
793                 ((*routeResp)->bounding_box).bottom_right.longitude = longitude;
794         }
795 }
796
797 static void __parse_route_response(char *response, int size, int *status, mapquest_route_resp_s **routeResp)
798 {
799         if (!response || !status || !routeResp) return;
800
801         *routeResp = NULL;
802
803         JsonParser *parser;
804         JsonNode *root;
805         JsonNode *node;
806         JsonObject *object;
807         GError *error = NULL;
808         char data[size + 1];
809
810         parser = json_parser_new();
811
812         strncpy(data, response, size);
813         data[size] = '\0';
814
815         if (!json_parser_load_from_data(parser, data, -1, &error)) {
816                 MAP_DEBUG("Error in file parsing JSON..");
817                 g_error_free(error);
818                 g_object_unref(parser);
819                 return;
820         }
821
822         root = json_parser_get_root(parser);
823
824         object = json_node_get_object(root);
825
826         node = json_object_get_member(object, "info");
827         JsonObject *infoObj = json_node_get_object(node);
828         if (infoObj) {
829                 JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
830
831                 if (statusNode) {
832                         *status = json_node_get_int(statusNode);
833                         MAP_DEBUG("status :: >>> %d", *status);
834                 }
835         }
836
837         if (*status != 0) {     /* SUCCESS */
838                 *routeResp = NULL;
839                 return;
840         }
841
842         *routeResp = (mapquest_route_resp_s *)g_malloc(sizeof(mapquest_route_resp_s));
843
844         if (!(*routeResp))
845                 return;
846
847         (*routeResp)->maneuvers = NULL;
848         (*routeResp)->shapePoints = NULL;
849
850         node = json_object_get_member(object, "route");
851
852         if (!node)
853                 return;
854
855         JsonObject *routeObject = json_node_get_object(node);
856
857         JsonNode *tmp = json_object_get_member(routeObject, "distance");
858
859         if (tmp) {
860                 double dist = json_node_get_double(tmp);
861                 (*routeResp)->distance = __convert_distance_unit(dist);
862                 (*routeResp)->distance_unit = __route_unit;
863         }
864
865         tmp = json_object_get_member(routeObject, "boundingBox");
866
867         if (tmp) {
868                 JsonObject *bbox = json_node_get_object(tmp);
869
870                 json_object_foreach_member(bbox, __bbox_foreach, routeResp);
871         }
872
873         tmp = json_object_get_member(routeObject, "formattedTime");
874
875         if (tmp)
876                 (*routeResp)->formatted_time = (char *) json_node_dup_string(tmp);
877
878         tmp = json_object_get_member(routeObject, "routeType");
879         if (tmp) {
880                 (*routeResp)->type = ROUTE_TYPE_BICYCLE;
881
882                 char *type = (char *) json_node_get_string(tmp);
883                 if (type) {
884                         if (!strcmp(type, "FASTEST"))
885                                 (*routeResp)->type = ROUTE_TYPE_FASTEST;
886                         else if (!strcmp(type, "SHORTEST"))
887                                 (*routeResp)->type = ROUTE_TYPE_SHORTEST;
888                         else if (!strcmp(type, "PEDESTRIAN"))
889                                 (*routeResp)->type = ROUTE_TYPE_PEDESTRIAN;
890                         else if (!strcmp(type, "MULTIMODAL"))
891                                 (*routeResp)->type = ROUTE_TYPE_MULTIMODAL;
892                 }
893         }
894
895         tmp = json_object_get_member(routeObject, "time");
896
897         if (tmp) {
898                 int time = json_node_get_int(tmp);
899                 (*routeResp)->time = time;
900         }
901
902         tmp = json_object_get_member(routeObject, "legs");
903
904         if (tmp) {
905                 JsonArray *legsArray = json_node_get_array(tmp);
906
907                 int length = json_array_get_length(legsArray);
908
909                 int index = 0;
910                 for (index = 0; index < length; index++) {
911
912                         JsonObject *obj = json_array_get_object_element(legsArray, index);
913
914                         if (obj) {
915                                 JsonNode *maneuversNode = json_object_get_member(obj, "maneuvers");
916
917                                 if (maneuversNode)
918                                         __parse_maneuvers(maneuversNode, routeResp);
919                         }
920                 }
921         }
922
923         tmp = json_object_get_member(routeObject, "shape");
924
925         if (tmp) {
926                 JsonObject *shape = json_node_get_object(tmp);
927
928                 json_object_foreach_member(shape, __shape_foreach, routeResp);
929         }
930
931         g_object_unref(parser);
932 }
933
934 void post_curl_response(char *response, int size, mapquest_resp_type type, void *user_data)
935 {
936         if (!response) return;
937
938         if (!user_data) {
939                 MAP_DEBUG("Response data is NULL");
940                 return;
941         }
942
943         MAP_DEBUG("Response received from Curl. [Size=%d]", size);
944         switch (type) {
945         case RESP_TYPE_GEOCODE:
946                 {
947                         MAP_DEBUG("Inside Geocode JSON Parsing..");
948                         int status = -1;
949                         MapquestGeocodeQueryData *queryData = (MapquestGeocodeQueryData *)user_data;
950                         MapquestGeocodeResponseData *responseData = (MapquestGeocodeResponseData *)g_malloc(sizeof(MapquestGeocodeResponseData));
951
952                         if (responseData) {
953                                 responseData->requestId = queryData->requestId;
954                                 responseData->geocode_cb = queryData->geocode_cb;
955                                 responseData->user_data = queryData->user_data;
956
957                                 if (response && (size > 0)) {
958                                         GList *coordsList = NULL;
959                                         __parse_geocode_response(response, size, &status, &coordsList);
960
961                                         if (coordsList != NULL) {
962                                                 /* Put the response in queue */
963                                                 responseData->error = __convert_status(status);
964                                                 responseData->coords = coordsList;
965                                         } else {
966                                                 /* Response parsing failure */
967                                                 responseData->error = __convert_status(status);
968                                                 responseData->coords = NULL;
969                                         }
970                                 } else {
971                                         responseData->error = __convert_status(status);
972                                         responseData->coords = NULL;
973                                 }
974
975                                 mapquest_push_to_queue(type, (gpointer)responseData);
976                         }
977
978                         if (queryData) {
979                                 g_free(queryData);
980                                 queryData = NULL;
981                         }
982                         break;
983                 }
984         case RESP_TYPE_REVGEOCODE:
985                 {
986                         MAP_DEBUG("Inside Rev Geocode JSON Parsing..");
987                         int status = -1;
988                         MapquestRevGeocodeQueryData *queryData = (MapquestRevGeocodeQueryData *)user_data;
989                         MapquestRevGeocodeResponseData *responseData = (MapquestRevGeocodeResponseData *)g_malloc(sizeof(MapquestRevGeocodeResponseData));
990
991                         if (responseData) {
992                                 responseData->requestId = queryData->requestId;
993                                 responseData->reverse_geocode_cb = queryData->reverse_geocode_cb;
994                                 responseData->user_data = queryData->user_data;
995
996                                 if (response && (size > 0)) {
997                                         /* Coords Result GList */
998                                         mapquest_address_resp_s *addrResponse = NULL;
999
1000                                         MAP_DEBUG("Rev Geocode :- Parsing json Response");
1001                                         __parse_revgeocode_response(response, size, &status, &addrResponse);
1002
1003                                         if (addrResponse != NULL) {
1004                                                 /* Put the response in queue */
1005                                                 responseData->error = __convert_status(status);
1006                                                 responseData->addressDetails = addrResponse;
1007                                         } else {
1008                                                 /* REPSONSE PARSING FAILURE */
1009                                                 MAP_DEBUG("addr Response is NULL");
1010                                                 responseData->error = __convert_status(status);
1011                                                 responseData->addressDetails = NULL;
1012                                         }
1013                                 } else {
1014                                         MAP_DEBUG("JSON Response is NULL..");
1015                                         responseData->error = __convert_status(status);
1016                                         responseData->addressDetails = NULL;
1017                                 }
1018
1019                                 mapquest_push_to_queue(type, (gpointer)responseData);
1020                         }
1021
1022                         if (queryData) {
1023                                 g_free(queryData);
1024                                 queryData = NULL;
1025                         }
1026                         break;
1027                 }
1028         case RESP_TYPE_PLACES:
1029                 {
1030                         MAP_DEBUG("Inside Places JSON Parsing..");
1031                         MapquestPlaceQueryData *queryData = (MapquestPlaceQueryData *)user_data;
1032                         MapquestPlaceResponseData *responseData = (MapquestPlaceResponseData *)g_malloc(sizeof(MapquestPlaceResponseData));
1033
1034                         if (responseData) {
1035                                 responseData->requestId = queryData->requestId;
1036                                 responseData->place_search_cb = queryData->place_search_cb;
1037                                 responseData->user_data = queryData->user_data;
1038
1039                                 if (response && (size > 0)) {
1040                                         /* Coords Result GList */
1041                                         GList *placeList = NULL;
1042
1043                                         MAP_DEBUG("Search Places :- Parsing Json Response");
1044                                         __parse_place_response(response, size, &placeList);
1045
1046                                         if (placeList != NULL) {
1047                                                 /* Put the response in queue */
1048                                                 responseData->error = MAPQUEST_ERROR_NONE;
1049                                                 responseData->places = placeList;
1050                                         } else {
1051                                                 /* REPSONSE PARSING FAILURE */
1052                                                 MAP_DEBUG("addr Response is NULL");
1053                                                 responseData->error = MAPQUEST_ERROR_UNKNOWN;
1054                                                 responseData->places = NULL;
1055                                         }
1056                                 } else {
1057                                         responseData->error = MAPQUEST_ERROR_UNKNOWN;
1058                                         responseData->places = NULL;
1059                                 }
1060
1061                                 mapquest_push_to_queue(type, (gpointer)responseData);
1062                         }
1063
1064                         if (queryData) {
1065                                 g_free(queryData);
1066                                 queryData = NULL;
1067                         }
1068
1069                         break;
1070                 }
1071         case RESP_TYPE_ROUTE:
1072                 {
1073                         MAP_DEBUG("Inside Route JSON Parsing..");
1074                         int status = -1;
1075                         MapquestRouteQueryData *queryData = (MapquestRouteQueryData *)user_data;
1076                         __route_unit = queryData->unit;
1077                         __maneuver_index = 0;
1078                         __destination_point = queryData->destination;
1079
1080                         MapquestRouteResponseData *responseData = (MapquestRouteResponseData *)g_malloc(sizeof(MapquestRouteResponseData));
1081
1082                         if (responseData) {
1083                                 responseData->requestId = queryData->requestId;
1084                                 responseData->route_cb = queryData->route_cb;
1085                                 responseData->user_data = queryData->user_data;
1086
1087                                 if (response && (size > 0)) {
1088                                         /* Coords Result GList */
1089                                         mapquest_route_resp_s *routeResponse = NULL;
1090
1091                                         MAP_DEBUG("Route :- Parsing Response");
1092                                         __parse_route_response(response, size, &status, &routeResponse);
1093
1094                                         if (routeResponse != NULL) {
1095                                                 /* Put the response in queue */
1096                                                 responseData->error = __convert_status(status);
1097                                                 responseData->routeResponse = routeResponse;
1098                                         } else {
1099                                                 /* REPSONSE PARSING FAILURE */
1100                                                 MAP_DEBUG("route Response is NULL");
1101                                                 responseData->error = __convert_status(status);
1102                                                 responseData->routeResponse = NULL;
1103                                         }
1104                                 } else {
1105                                         responseData->error = __convert_status(status);
1106                                         responseData->routeResponse = NULL;
1107                                 }
1108
1109                                 mapquest_push_to_queue(type, (gpointer)responseData);
1110                         }
1111
1112                         if (queryData) {
1113                                 g_free(queryData);
1114                                 queryData = NULL;
1115                         }
1116
1117                         break;
1118                 }
1119         default:
1120                 {
1121                         MAP_DEBUG("Inside default JSON Parsing..");
1122                         break;
1123                 }
1124         }
1125 }