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