diff options
Diffstat (limited to 'src/mapquest/mapquest_jsonparser.c')
-rw-r--r-- | src/mapquest/mapquest_jsonparser.c | 1124 |
1 files changed, 1124 insertions, 0 deletions
diff --git a/src/mapquest/mapquest_jsonparser.c b/src/mapquest/mapquest_jsonparser.c new file mode 100644 index 0000000..e549a5c --- /dev/null +++ b/src/mapquest/mapquest_jsonparser.c @@ -0,0 +1,1124 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <json-glib/json-glib.h> +#include "mapquest_jsonparser.h" +#include "mapquest_queue.h" +#include "mapquest_debug.h" + +#define ROUTE_UNIT_CONVERSION_MILE_TO_M(x) (1609.34 * (x)) +#define ROUTE_UNIT_CONVERSION_MILE_TO_KM(x) (1.60934 * (x)) +#define ROUTE_UNIT_CONVERSION_MILE_TO_FT(x) (5280 * (x)) +#define ROUTE_UNIT_CONVERSION_MILE_TO_YD(x) (1760 * (x)) + +static route_unit __route_unit = ROUTE_UNIT_M; +static int __maneuver_index = 0; +static coords_s __destination_point; + +static mapquest_error_e __convert_status(int status) +{ + mapquest_error_e error = MAPQUEST_ERROR_UNKNOWN; + switch (status) { + case 0: + { + /* Successful Geocode call */ + error = MAPQUEST_ERROR_NONE; + break; + } + case 400: + { + /* Error with input - Illegal argument from request */ + error = MAPQUEST_ERROR_INVALID_PARAMETER; + break; + } + case 403: + { + /* Key related error - Invalid key */ + error = MAPQUEST_ERROR_KEY_NOT_AVAILABLE; + break; + } + case 500: + { + /* Unknown error */ + error = MAPQUEST_ERROR_UNKNOWN; + break; + } + case -1: + { + /* Network error */ + error = MAPQUEST_ERROR_NETWORK_UNREACHABLE; + break; + } + } + + return error; +} + +/************ GEOCODE ***************/ + +static void __parse_lat_lng(JsonNode *node, GList **coordsList) +{ + if (!node || !coordsList) return; + + gdouble latitude = 0.0; + gdouble longitude = 0.0; + JsonObject *resultObj = json_node_get_object(node); + + if (resultObj) { + JsonNode *latNode = json_object_get_member(resultObj, "lat"); + + if (latNode) { + latitude = json_node_get_double(latNode); + MAP_DEBUG("Latitude :: >>> %f", latitude); + } + + JsonNode *lngNode = json_object_get_member(resultObj, "lng"); + + if (lngNode) { + longitude = json_node_get_double(lngNode); + MAP_DEBUG("Longitude :: >>> %f", longitude); + } + + coords_s *coords = (coords_s *)g_malloc0(sizeof(coords_s)); + if (coords != NULL) { + MAP_DEBUG("Storing the latitude and longitude data.."); + coords->latitude = latitude; + coords->longitude = longitude; + } + + if (*coordsList == NULL) + *coordsList = g_list_append(*coordsList, coords); + else + *coordsList = g_list_insert_before(*coordsList, NULL, coords); + } +} + +static void __parse_locations(JsonNode *node, GList **coordsList) +{ + if (!node || !coordsList) return; + + JsonArray *resultArray = json_node_get_array(node); + + int length = json_array_get_length(resultArray); + + int index = 0; + for (index = 0; index < length; index++) { + + JsonObject *obj = json_array_get_object_element(resultArray, index); + + if (obj) { + JsonNode *latLngNode = json_object_get_member(obj, "latLng"); + + if (latLngNode) + __parse_lat_lng(latLngNode, coordsList); + } + } +} + +static void __parse_geocode_response(char *response, int size, int *status, GList **coordsList) +{ + if (!response || !status || !coordsList) return; + + *coordsList = NULL; + + JsonParser *parser = NULL; + JsonNode *root = NULL; + JsonNode *node = NULL; + JsonObject *object = NULL; + GError *error = NULL; + char data[size + 1]; + + parser = json_parser_new(); + + strncpy(data, response, size); + data[size] = '\0'; + + if (!json_parser_load_from_data(parser, data, -1, &error)) { + MAP_DEBUG("Error in file parsing JSON.."); + g_error_free(error); + g_object_unref(parser); + return; + } + + root = json_parser_get_root(parser); + + object = json_node_get_object(root); + + node = json_object_get_member(object, "info"); + JsonObject *infoObj = json_node_get_object(node); + if (infoObj) { + JsonNode *statusNode = json_object_get_member(infoObj, "statuscode"); + + if (statusNode) { + *status = json_node_get_int(statusNode); + MAP_DEBUG("status :: >>> %d", *status); + } + } + + if (*status != 0) { /* SUCCESS */ + *coordsList = NULL; + return; + } + + node = json_object_get_member(object, "results"); + JsonArray *resultArray = json_node_get_array(node); + + int length = json_array_get_length(resultArray); + + int index = 0; + for (index = 0; index < length; index++) { + + JsonObject *obj = json_array_get_object_element(resultArray, index); + + if (obj) { + JsonNode *locNode = json_object_get_member(obj, "locations"); + + if (locNode) + __parse_locations(locNode, coordsList); + } + } + + g_object_unref(parser); +} + +/****************** REVERSE GEOCODE *********************/ + +static void __parse_revgeocode_address(JsonNode *node, mapquest_address_resp_s **respAddr) +{ + if (!node || !respAddr) return; + + char *streetAddr = NULL; + char *neighbourhood = NULL; + char *city = NULL; + char *county = NULL; + char *state = NULL; + char *country = NULL; + char *postalCode = NULL; + + JsonArray *resultArray = json_node_get_array(node); + + int length = json_array_get_length(resultArray); + + int index = 0; + for (index = 0; index < length; index++) { + + JsonObject *obj = json_array_get_object_element(resultArray, index); + + if (obj) { + JsonNode *tmp = NULL; + + /* Street */ + tmp = json_object_get_member(obj, "street"); + if (tmp) { + streetAddr = (char *) json_node_get_string(tmp); + if (streetAddr && strlen(streetAddr) <= 0) + streetAddr = NULL; + } else { + streetAddr = NULL; + } + + /* Neighborhood */ + tmp = json_object_get_member(obj, "adminArea6"); + if (tmp) { + neighbourhood = (char *) json_node_get_string(tmp); + if (neighbourhood && strlen(neighbourhood) <= 0) + neighbourhood = NULL; + } else { + neighbourhood = NULL; + } + + /* City */ + tmp = json_object_get_member(obj, "adminArea5"); + if (tmp) { + city = (char *) json_node_get_string(tmp); + if (city && strlen(city) <= 0) + city = NULL; + } else { + city = NULL; + } + + /* State */ + tmp = json_object_get_member(obj, "adminArea3"); + if (tmp) { + state = (char *) json_node_get_string(tmp); + if (state && strlen(state) <= 0) + state = NULL; + } else { + state = NULL; + } + + /* County */ + tmp = json_object_get_member(obj, "adminArea4"); + if (tmp) { + county = (char *) json_node_get_string(tmp); + if (county && strlen(county) <= 0) + county = NULL; + } else { + county = NULL; + } + + /* Country */ + tmp = json_object_get_member(obj, "adminArea1"); + if (tmp) { + country = (char *) json_node_get_string(tmp); + if (country && strlen(country) <= 0) + country = NULL; + } else { + country = NULL; + } + + /* Postal Code */ + tmp = json_object_get_member(obj, "postalCode"); + if (tmp) { + postalCode = (char *) json_node_get_string(tmp); + if (postalCode && strlen(postalCode) <= 0) + postalCode = NULL; + } else { + postalCode = NULL; + } + + if (!streetAddr && !neighbourhood && !city && !state && !county && !country && !postalCode) + continue; + + *respAddr = (mapquest_address_resp_s *)g_malloc(sizeof(mapquest_address_resp_s)); + + if (*respAddr != NULL) { + /* Street Address */ + if (streetAddr != NULL) { + (*respAddr)->street_add = (gchar *)g_malloc(strlen((char *)streetAddr) + 1); + strcpy((*respAddr)->street_add, (char *) streetAddr); + } else { + MAP_DEBUG("street is NULL"); + (*respAddr)->street_add = NULL; + } + + /* Neighbourhood */ + if (neighbourhood != NULL) { + (*respAddr)->neighbourhood = (gchar *)g_malloc(strlen((char *)neighbourhood) + 1); + strcpy((*respAddr)->neighbourhood, (char *) neighbourhood); + } else { + MAP_DEBUG("neighbourhood is NULL"); + (*respAddr)->neighbourhood = NULL; + } + + /* City */ + if (city != NULL) { + (*respAddr)->city = (gchar *)g_malloc(strlen((char *)city) + 1); + strcpy((*respAddr)->city, (char *) city); + } else { + MAP_DEBUG("city is NULL"); + (*respAddr)->city = NULL; + } + + /* County */ + if (county != NULL) { + (*respAddr)->county = (gchar *)g_malloc(strlen((char *)county) + 1); + strcpy((*respAddr)->county, (char *) county); + } else { + MAP_DEBUG("county is NULL"); + (*respAddr)->county = NULL; + } + + /* State */ + if (state != NULL) { + (*respAddr)->state = (gchar *)g_malloc(strlen((char *)state) + 1); + strcpy((*respAddr)->state, (char *) state); + } else { + MAP_DEBUG("state is NULL"); + (*respAddr)->state = NULL; + } + + /* Country */ + if (country != NULL) { + (*respAddr)->country = (gchar *)g_malloc(strlen((char *)country) + 1); + strcpy((*respAddr)->country, (char *) country); + } else { + MAP_DEBUG("country is NULL"); + (*respAddr)->country = NULL; + } + + /* Country code */ + MAP_DEBUG("country code is NULL"); + (*respAddr)->country_code = NULL; + + /* Postal Code */ + if (postalCode != NULL) { + (*respAddr)->postal_code = (gchar *)g_malloc(strlen((char *)postalCode) + 1); + strcpy((*respAddr)->postal_code, (char *) postalCode); + } else { + MAP_DEBUG("postal_code is NULL"); + (*respAddr)->postal_code = NULL; + } + } + } + } +} + +static void __parse_revgeocode_response(char *response, int size, int *status, mapquest_address_resp_s **respAddr) +{ + if (!response || !status || !respAddr) return; + + *respAddr = NULL; + + JsonParser *parser; + JsonNode *root; + JsonNode *node; + JsonObject *object; + GError *error = NULL; + char data[size + 1]; + + parser = json_parser_new(); + + strncpy(data, response, size); + data[size] = '\0'; + + if (!json_parser_load_from_data(parser, data, -1, &error)) { + MAP_DEBUG("Error in file parsing JSON.."); + g_error_free(error); + g_object_unref(parser); + return; + } + + root = json_parser_get_root(parser); + + object = json_node_get_object(root); + + node = json_object_get_member(object, "info"); + JsonObject *infoObj = json_node_get_object(node); + if (infoObj) { + JsonNode *statusNode = json_object_get_member(infoObj, "statuscode"); + + if (statusNode) { + *status = json_node_get_int(statusNode); + MAP_DEBUG("status :: >>> %d", *status); + } + } + + if (*status != 0) { /* SUCCESS */ + *respAddr = NULL; + return; + } + + node = json_object_get_member(object, "results"); + JsonArray *resultArray = json_node_get_array(node); + + int length = json_array_get_length(resultArray); + + int index = 0; + for (index = 0; index < length; index++) { + + JsonObject *obj = json_array_get_object_element(resultArray, index); + + if (obj) { + JsonNode *locNode = json_object_get_member(obj, "locations"); + + if (locNode) + __parse_revgeocode_address(locNode, respAddr); + } + } + + g_object_unref(parser); +} + +/**************** PLACE SEARCH ********************/ + +static void __place_address_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data) +{ + if (!object || !member_name || !member_node || !user_data) return; + + mapquest_address_resp_s **respAddr = (mapquest_address_resp_s **) user_data; + + if (*respAddr) { + JsonNode *tmp = json_object_get_member(object, member_name); + + if (!strcmp(member_name, "road")) + (*respAddr)->street_add = (char *) json_node_dup_string(tmp); + else if (!strcmp(member_name, "neighbourhood")) + (*respAddr)->neighbourhood = (char *) json_node_dup_string(tmp); + else if (!strcmp(member_name, "house_number")) + (*respAddr)->building_number = (char *) json_node_dup_string(tmp); + else if (!strcmp(member_name, "city")) + (*respAddr)->city = (char *) json_node_dup_string(tmp); + else if (!strcmp(member_name, "county")) + (*respAddr)->county = (char *) json_node_dup_string(tmp); + else if (!strcmp(member_name, "state")) + (*respAddr)->state = (char *) json_node_dup_string(tmp); + else if (!strcmp(member_name, "country")) + (*respAddr)->country = (char *) json_node_dup_string(tmp); + else if (!strcmp(member_name, "country_code")) + (*respAddr)->country_code = (char *) json_node_dup_string(tmp); + else if (!strcmp(member_name, "postcode")) + (*respAddr)->postal_code = (char *) json_node_dup_string(tmp); + } else { + *respAddr = NULL; + } +} + +static void __place_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data) +{ + if (!object || !member_name || !member_node || !user_data) return; + + mapquest_place_resp_s **respPlaces = (mapquest_place_resp_s **) user_data; + + JsonNode *tmp = json_object_get_member(object, member_name); + char *str; + + if (!strcmp(member_name, "place_id")) { + (*respPlaces)->place_id = (char *) json_node_get_string(tmp); + } else if (!strcmp(member_name, "lat")) { + str = (char *) json_node_get_string(tmp); + ((*respPlaces)->coordinates).latitude = (str ? atof(str) : 0); + } else if (!strcmp(member_name, "lon")) { + str = (char *) json_node_get_string(tmp); + ((*respPlaces)->coordinates).longitude = (str ? atof(str) : 0); + } else if (!strcmp(member_name, "class")) { + (*respPlaces)->category = (char *) json_node_dup_string(tmp); + } else if (!strcmp(member_name, "type")) { + (*respPlaces)->subcategory = (char *) json_node_dup_string(tmp); + } else if (!strcmp(member_name, "display_name")) { + (*respPlaces)->display_name = (char *) json_node_dup_string(tmp); + } else if (!strcmp(member_name, "address")) { + JsonObject *obj = json_node_get_object(member_node); + + (*respPlaces)->address = (mapquest_address_resp_s *)g_malloc(sizeof(mapquest_address_resp_s)); + if ((*respPlaces)->address) { + (*respPlaces)->address->street_add = NULL; + (*respPlaces)->address->neighbourhood = NULL; + (*respPlaces)->address->building_number = NULL; + (*respPlaces)->address->city = NULL; + (*respPlaces)->address->county = NULL; + (*respPlaces)->address->state = NULL; + (*respPlaces)->address->country = NULL; + (*respPlaces)->address->country_code = NULL; + (*respPlaces)->address->postal_code = NULL; + } + + json_object_foreach_member(obj, __place_address_foreach, &((*respPlaces)->address)); + } else if (!strcmp(member_name, "icon")) { + (*respPlaces)->icon_url = (char *) json_node_get_string(tmp); + } +} + +static void __parse_place_response(char *response, int size, GList **placeList) +{ + if (!response || !placeList) return; + + *placeList = NULL; + + JsonParser *parser; + JsonNode *root; + GError *error = NULL; + char data[size + 1]; + + parser = json_parser_new(); + if (!parser) return; + + strncpy(data, response, size); + data[size] = '\0'; + + if (!json_parser_load_from_data(parser, data, -1, &error)) { + MAP_DEBUG("Error in file parsing JSON.."); + g_error_free(error); + g_object_unref(parser); + return; + } + + root = json_parser_get_root(parser); + + JsonArray *placeArray = json_node_get_array(root); + + int length = json_array_get_length(placeArray); + MAP_DEBUG("Places result count :: %d", length); + + int index = 0; + for (index = 0; index < length; index++) { + + JsonObject *obj = json_array_get_object_element(placeArray, index); + + if (obj) { + mapquest_place_resp_s *respPlaces = (mapquest_place_resp_s *)g_malloc(sizeof(mapquest_place_resp_s)); + + if (respPlaces) { + respPlaces->place_id = NULL; + respPlaces->category = NULL; + respPlaces->subcategory = NULL; + respPlaces->display_name = NULL; + respPlaces->address = NULL; + respPlaces->icon_url = NULL; + + json_object_foreach_member(obj, __place_foreach, &respPlaces); + + if (*placeList == NULL) + *placeList = g_list_append(*placeList, respPlaces); + else + *placeList = g_list_insert_before(*placeList, NULL, respPlaces); + } + } + } + + g_object_unref(parser); +} + +/********************* ROUTE RESPONSE ***********************/ + +static double __convert_distance_unit(double distance) +{ + double val = 0.0; + switch (__route_unit) { + case ROUTE_UNIT_M: + val = ROUTE_UNIT_CONVERSION_MILE_TO_M(distance); + break; + case ROUTE_UNIT_KM: + val = ROUTE_UNIT_CONVERSION_MILE_TO_KM(distance); + break; + case ROUTE_UNIT_FT: + val = ROUTE_UNIT_CONVERSION_MILE_TO_FT(distance); + break; + case ROUTE_UNIT_YD: + val = ROUTE_UNIT_CONVERSION_MILE_TO_YD(distance); + break; + } + + return val; +} + +static void __maneuver_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data) +{ + if (!object || !member_name || !member_node || !user_data) return; + + mapquest_route_maneuver **maneuver = (mapquest_route_maneuver **) user_data; + + JsonNode *tmp = json_object_get_member(object, member_name); + + if (!strcmp(member_name, "startPoint")) { + JsonObject *coordsObj = json_node_get_object(tmp); + + if (coordsObj) { + double latitude = 0.0; + double longitude = 0.0; + JsonNode *latNode = json_object_get_member(coordsObj, "lat"); + + if (latNode) + latitude = json_node_get_double(latNode); + + JsonNode *lngNode = json_object_get_member(coordsObj, "lng"); + + if (lngNode) + longitude = json_node_get_double(lngNode); + + coords_s start_point; + start_point.latitude = latitude; + start_point.longitude = longitude; + + (*maneuver)->start_point = start_point; + } + } else if (!strcmp(member_name, "narrative")) { + (*maneuver)->instruction = (char *) json_node_dup_string(tmp); + } else if (!strcmp(member_name, "distance")) { + double dist = json_node_get_double(tmp); + (*maneuver)->distance = __convert_distance_unit(dist); + } else if (!strcmp(member_name, "time")) { + (*maneuver)->time = json_node_get_int(tmp); + } else if (!strcmp(member_name, "formattedTime")) { + (*maneuver)->formatted_time = (char *) json_node_dup_string(tmp); + } else if (!strcmp(member_name, "attributes")) { + (*maneuver)->attribute = json_node_get_int(tmp); + } else if (!strcmp(member_name, "turnType")) { + (*maneuver)->turn_type = json_node_get_int(tmp); + } else if (!strcmp(member_name, "direction")) { + (*maneuver)->direction = json_node_get_int(tmp); + } else if (!strcmp(member_name, "directionName")) { + (*maneuver)->direction_name = (char *) json_node_dup_string(tmp); + } else if (!strcmp(member_name, "index")) { + (*maneuver)->index = json_node_get_int(tmp); + } else if (!strcmp(member_name, "streets")) { + JsonArray *streetsArray = json_node_get_array(tmp); + + int length = json_array_get_length(streetsArray); + + char street_name[512]; + strcpy(street_name, ""); + int index = 0; + for (index = 0; index < length; index++) { + char *name = (char *) json_array_get_string_element(streetsArray, index); + if (name) { + if (index == 0) { + strncpy(street_name, name, sizeof(street_name)-1); + } else { + strcat(street_name, "/"); + strncat(street_name, name, sizeof(street_name)-strlen(street_name)-1); + } + } + } + + if (strlen(street_name) > 0) { + (*maneuver)->street_name = (gchar *)g_malloc0((strlen((char *)street_name)) + 1); + if ((*maneuver)->street_name) + strcpy((*maneuver)->street_name, (char *) street_name); + } else { + (*maneuver)->street_name = NULL; + } + } +} + +static void __parse_maneuvers(JsonNode *node, mapquest_route_resp_s **routeResp) +{ + if (!node || !routeResp) return; + + JsonArray *resultArray = json_node_get_array(node); + + int length = json_array_get_length(resultArray); + + int index = 0; + for (index = 0; index < length; index++) { + + JsonObject *obj = json_array_get_object_element(resultArray, index); + + if (obj) { + mapquest_route_maneuver *maneuver = (mapquest_route_maneuver *)g_malloc(sizeof(mapquest_route_maneuver)); + + if (maneuver) { + json_object_foreach_member(obj, __maneuver_foreach, &maneuver); + + if (__maneuver_index != 0) { + if (maneuver->distance == 0.0 && maneuver->time == 0) { + maneuver->start_point = __destination_point; + maneuver->end_point = __destination_point; + } else { + + } + + GList *list = NULL; + list = g_list_last((*routeResp)->maneuvers); + if (list) { + mapquest_route_maneuver *tmp = (mapquest_route_maneuver *)list->data; + tmp->end_point = maneuver->start_point; + } + } + + if ((*routeResp)->maneuvers == NULL) + (*routeResp)->maneuvers = g_list_append((*routeResp)->maneuvers, (gpointer)maneuver); + else + (*routeResp)->maneuvers = g_list_insert_before((*routeResp)->maneuvers, NULL, (gpointer)maneuver); + } + __maneuver_index++; + } + } +} + +static void __shape_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data) +{ + if (!object || !member_name || !member_node || !user_data) return; + + mapquest_route_resp_s **routeResp = (mapquest_route_resp_s **) user_data; + + JsonNode *tmp = json_object_get_member(object, member_name); + + if (!strcmp(member_name, "shapePoints")) { + JsonArray *shapePointsArray = json_node_get_array(tmp); + + int length = json_array_get_length(shapePointsArray); + + int index = 0; + double val = 0.0; + coords_s *coords = NULL; + for (index = 0; index < length; index++) { + + val = (double) json_array_get_double_element(shapePointsArray, index); + + if ((index % 2) == 0) { + /* Lat */ + coords = (coords_s *)g_malloc0(sizeof(coords_s)); + if (coords) + coords->latitude = val; + } else { + /* Lon */ + if (coords) { + coords->longitude = val; + if ((*routeResp)->shapePoints == NULL) + (*routeResp)->shapePoints = g_list_append((*routeResp)->shapePoints, (gpointer)coords); + else + (*routeResp)->shapePoints = g_list_insert_before((*routeResp)->shapePoints, NULL, (gpointer)coords); + } + } + } + } + +} + +static void __bbox_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data) +{ + if (!object || !member_name || !member_node || !user_data) return; + + mapquest_route_resp_s **routeResp = (mapquest_route_resp_s **) user_data; + + JsonNode *tmp = json_object_get_member(object, member_name); + + JsonObject *coordsObj = json_node_get_object(tmp); + double latitude = 0.0; + double longitude = 0.0; + + if (coordsObj) { + JsonNode *latNode = json_object_get_member(coordsObj, "lat"); + + if (latNode) + latitude = json_node_get_double(latNode); + + JsonNode *lngNode = json_object_get_member(coordsObj, "lng"); + + if (lngNode) + longitude = json_node_get_double(lngNode); + } + + if (!strcmp(member_name, "ul")) { + ((*routeResp)->bounding_box).top_left.latitude = latitude; + ((*routeResp)->bounding_box).top_left.longitude = longitude; + } else if (!strcmp(member_name, "lr")) { + ((*routeResp)->bounding_box).bottom_right.latitude = latitude; + ((*routeResp)->bounding_box).bottom_right.longitude = longitude; + } +} + +static void __parse_route_response(char *response, int size, int *status, mapquest_route_resp_s **routeResp) +{ + if (!response || !status || !routeResp) return; + + *routeResp = NULL; + + JsonParser *parser; + JsonNode *root; + JsonNode *node; + JsonObject *object; + GError *error = NULL; + char data[size + 1]; + + parser = json_parser_new(); + + strncpy(data, response, size); + data[size] = '\0'; + + if (!json_parser_load_from_data(parser, data, -1, &error)) { + MAP_DEBUG("Error in file parsing JSON.."); + g_error_free(error); + g_object_unref(parser); + return; + } + + root = json_parser_get_root(parser); + + object = json_node_get_object(root); + + node = json_object_get_member(object, "info"); + JsonObject *infoObj = json_node_get_object(node); + if (infoObj) { + JsonNode *statusNode = json_object_get_member(infoObj, "statuscode"); + + if (statusNode) { + *status = json_node_get_int(statusNode); + MAP_DEBUG("status :: >>> %d", *status); + } + } + + if (*status != 0) { /* SUCCESS */ + *routeResp = NULL; + return; + } + + *routeResp = (mapquest_route_resp_s *)g_malloc(sizeof(mapquest_route_resp_s)); + + if (!(*routeResp)) + return; + + (*routeResp)->maneuvers = NULL; + (*routeResp)->shapePoints = NULL; + + node = json_object_get_member(object, "route"); + + if (!node) + return; + + JsonObject *routeObject = json_node_get_object(node); + + JsonNode *tmp = json_object_get_member(routeObject, "distance"); + + if (tmp) { + double dist = json_node_get_double(tmp); + (*routeResp)->distance = __convert_distance_unit(dist); + (*routeResp)->distance_unit = __route_unit; + } + + tmp = json_object_get_member(routeObject, "boundingBox"); + + if (tmp) { + JsonObject *bbox = json_node_get_object(tmp); + + json_object_foreach_member(bbox, __bbox_foreach, routeResp); + } + + tmp = json_object_get_member(routeObject, "formattedTime"); + + if (tmp) + (*routeResp)->formatted_time = (char *) json_node_dup_string(tmp); + + tmp = json_object_get_member(routeObject, "routeType"); + if (tmp) { + (*routeResp)->type = ROUTE_TYPE_BICYCLE; + + char *type = (char *) json_node_get_string(tmp); + if (type) { + if (!strcmp(type, "FASTEST")) + (*routeResp)->type = ROUTE_TYPE_FASTEST; + else if (!strcmp(type, "SHORTEST")) + (*routeResp)->type = ROUTE_TYPE_SHORTEST; + else if (!strcmp(type, "PEDESTRIAN")) + (*routeResp)->type = ROUTE_TYPE_PEDESTRIAN; + else if (!strcmp(type, "MULTIMODAL")) + (*routeResp)->type = ROUTE_TYPE_MULTIMODAL; + } + } + + tmp = json_object_get_member(routeObject, "time"); + + if (tmp) { + int time = json_node_get_int(tmp); + (*routeResp)->time = time; + } + + tmp = json_object_get_member(routeObject, "legs"); + + if (tmp) { + JsonArray *legsArray = json_node_get_array(tmp); + + int length = json_array_get_length(legsArray); + + int index = 0; + for (index = 0; index < length; index++) { + + JsonObject *obj = json_array_get_object_element(legsArray, index); + + if (obj) { + JsonNode *maneuversNode = json_object_get_member(obj, "maneuvers"); + + if (maneuversNode) + __parse_maneuvers(maneuversNode, routeResp); + } + } + } + + tmp = json_object_get_member(routeObject, "shape"); + + if (tmp) { + JsonObject *shape = json_node_get_object(tmp); + + json_object_foreach_member(shape, __shape_foreach, routeResp); + } + + g_object_unref(parser); +} + +void post_curl_response(char *response, int size, mapquest_resp_type type, void *user_data) +{ + if (!response) return; + + if (!user_data) { + MAP_DEBUG("Response data is NULL"); + return; + } + + MAP_DEBUG("Response received from Curl. [Size=%d]", size); + switch (type) { + case RESP_TYPE_GEOCODE: + { + MAP_DEBUG("Inside Geocode JSON Parsing.."); + int status = -1; + MapquestGeocodeQueryData *queryData = (MapquestGeocodeQueryData *)user_data; + MapquestGeocodeResponseData *responseData = (MapquestGeocodeResponseData *)g_malloc(sizeof(MapquestGeocodeResponseData)); + + if (responseData) { + responseData->requestId = queryData->requestId; + responseData->geocode_cb = queryData->geocode_cb; + responseData->user_data = queryData->user_data; + + if (response && (size > 0)) { + GList *coordsList = NULL; + __parse_geocode_response(response, size, &status, &coordsList); + + if (coordsList != NULL) { + /* Put the response in queue */ + responseData->error = __convert_status(status); + responseData->coords = coordsList; + } else { + /* Response parsing failure */ + responseData->error = __convert_status(status); + responseData->coords = NULL; + } + } else { + responseData->error = __convert_status(status); + responseData->coords = NULL; + } + + mapquest_push_to_queue(type, (gpointer)responseData); + } + + if (queryData) { + g_free(queryData); + queryData = NULL; + } + break; + } + case RESP_TYPE_REVGEOCODE: + { + MAP_DEBUG("Inside Rev Geocode JSON Parsing.."); + int status = -1; + MapquestRevGeocodeQueryData *queryData = (MapquestRevGeocodeQueryData *)user_data; + MapquestRevGeocodeResponseData *responseData = (MapquestRevGeocodeResponseData *)g_malloc(sizeof(MapquestRevGeocodeResponseData)); + + if (responseData) { + responseData->requestId = queryData->requestId; + responseData->reverse_geocode_cb = queryData->reverse_geocode_cb; + responseData->user_data = queryData->user_data; + + if (response && (size > 0)) { + /* Coords Result GList */ + mapquest_address_resp_s *addrResponse = NULL; + + MAP_DEBUG("Rev Geocode :- Parsing json Response"); + __parse_revgeocode_response(response, size, &status, &addrResponse); + + if (addrResponse != NULL) { + /* Put the response in queue */ + responseData->error = __convert_status(status); + responseData->addressDetails = addrResponse; + } else { + /* REPSONSE PARSING FAILURE */ + MAP_DEBUG("addr Response is NULL"); + responseData->error = __convert_status(status); + responseData->addressDetails = NULL; + } + } else { + MAP_DEBUG("JSON Response is NULL.."); + responseData->error = __convert_status(status); + responseData->addressDetails = NULL; + } + + mapquest_push_to_queue(type, (gpointer)responseData); + } + + if (queryData) { + g_free(queryData); + queryData = NULL; + } + break; + } + case RESP_TYPE_PLACES: + { + MAP_DEBUG("Inside Places JSON Parsing.."); + MapquestPlaceQueryData *queryData = (MapquestPlaceQueryData *)user_data; + MapquestPlaceResponseData *responseData = (MapquestPlaceResponseData *)g_malloc(sizeof(MapquestPlaceResponseData)); + + if (responseData) { + responseData->requestId = queryData->requestId; + responseData->place_search_cb = queryData->place_search_cb; + responseData->user_data = queryData->user_data; + + if (response && (size > 0)) { + /* Coords Result GList */ + GList *placeList = NULL; + + MAP_DEBUG("Search Places :- Parsing Json Response"); + __parse_place_response(response, size, &placeList); + + if (placeList != NULL) { + /* Put the response in queue */ + responseData->error = MAPQUEST_ERROR_NONE; + responseData->places = placeList; + } else { + /* REPSONSE PARSING FAILURE */ + MAP_DEBUG("addr Response is NULL"); + responseData->error = MAPQUEST_ERROR_UNKNOWN; + responseData->places = NULL; + } + } else { + responseData->error = MAPQUEST_ERROR_UNKNOWN; + responseData->places = NULL; + } + + mapquest_push_to_queue(type, (gpointer)responseData); + } + + if (queryData) { + g_free(queryData); + queryData = NULL; + } + + break; + } + case RESP_TYPE_ROUTE: + { + MAP_DEBUG("Inside Route JSON Parsing.."); + int status = -1; + MapquestRouteQueryData *queryData = (MapquestRouteQueryData *)user_data; + __route_unit = queryData->unit; + __maneuver_index = 0; + __destination_point = queryData->destination; + + MapquestRouteResponseData *responseData = (MapquestRouteResponseData *)g_malloc(sizeof(MapquestRouteResponseData)); + + if (responseData) { + responseData->requestId = queryData->requestId; + responseData->route_cb = queryData->route_cb; + responseData->user_data = queryData->user_data; + + if (response && (size > 0)) { + /* Coords Result GList */ + mapquest_route_resp_s *routeResponse = NULL; + + MAP_DEBUG("Route :- Parsing Response"); + __parse_route_response(response, size, &status, &routeResponse); + + if (routeResponse != NULL) { + /* Put the response in queue */ + responseData->error = __convert_status(status); + responseData->routeResponse = routeResponse; + } else { + /* REPSONSE PARSING FAILURE */ + MAP_DEBUG("route Response is NULL"); + responseData->error = __convert_status(status); + responseData->routeResponse = NULL; + } + } else { + responseData->error = __convert_status(status); + responseData->routeResponse = NULL; + } + + mapquest_push_to_queue(type, (gpointer)responseData); + } + + if (queryData) { + g_free(queryData); + queryData = NULL; + } + + break; + } + default: + { + MAP_DEBUG("Inside default JSON Parsing.."); + break; + } + } +} |