From 3ae47a6a58cf7b8b502ead037592b9a2c6ba41b2 Mon Sep 17 00:00:00 2001 From: Minjune Kim Date: Tue, 21 Aug 2012 18:23:26 +0900 Subject: [PATCH] Release Tizen2.0 beta --- LICENSE | 206 ++++ Makefile.am | 6 + autogen.sh | 21 + configure.ac | 147 +++ crypt/Makefile.am | 21 + crypt/conf.org | 6 + crypt/cryption.c | 231 ++++ crypt/cryption.h | 36 + crypt/docrypt.c | 72 ++ debian/changelog | 449 ++++++++ debian/compat | 1 + debian/control | 42 + debian/elementary-decarta.install.in | 1 + debian/libdecarta-dev.install.in | 3 + debian/libdecarta.install.in | 2 + debian/libdecarta.postinst | 7 + debian/location-decarta.install.in | 1 + debian/rules | 120 +++ decarta.pc.in | 13 + decarta/Makefile.am | 48 + decarta/decarta.h | 32 + decarta/decarta_config.c | 197 ++++ decarta/decarta_config.h | 38 + decarta/decarta_directory.c | 271 +++++ decarta/decarta_directory.h | 39 + decarta/decarta_geocode.c | 226 ++++ decarta/decarta_geocode.h | 46 + decarta/decarta_log.h | 46 + decarta/decarta_maps.c | 243 +++++ decarta/decarta_maps.h | 37 + decarta/decarta_route.c | 271 +++++ decarta/decarta_route.h | 38 + decarta/decarta_types.c | 947 +++++++++++++++++ decarta/decarta_types.h | 318 ++++++ decarta/decarta_xml.h | 51 + decarta/decarta_xml_directory.c | 261 +++++ decarta/decarta_xml_geocode.c | 166 +++ decarta/decarta_xml_internal.c | 376 +++++++ decarta/decarta_xml_internal.h | 64 ++ decarta/decarta_xml_maps.c | 132 +++ decarta/decarta_xml_route.c | 568 ++++++++++ decarta/http_wrapper.c | 303 ++++++ decarta/http_wrapper.h | 47 + decarta/xml_wrapper.c | 1944 ++++++++++++++++++++++++++++++++++ decarta/xml_wrapper.h | 124 +++ elm_module/Makefile.am | 19 + elm_module/decarta.c | 379 +++++++ location_module/Makefile.am | 15 + location_module/location_decarta.c | 1740 ++++++++++++++++++++++++++++++ location_module/location_decarta.h | 119 +++ packaging/libdecarta.spec | 117 ++ tests/Makefile.am | 11 + tests/decarta_test.c | 967 +++++++++++++++++ 53 files changed, 11585 insertions(+) create mode 100755 LICENSE create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100755 configure.ac create mode 100644 crypt/Makefile.am create mode 100644 crypt/conf.org create mode 100644 crypt/cryption.c create mode 100644 crypt/cryption.h create mode 100644 crypt/docrypt.c create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/elementary-decarta.install.in create mode 100644 debian/libdecarta-dev.install.in create mode 100644 debian/libdecarta.install.in create mode 100644 debian/libdecarta.postinst create mode 100644 debian/location-decarta.install.in create mode 100755 debian/rules create mode 100644 decarta.pc.in create mode 100644 decarta/Makefile.am create mode 100644 decarta/decarta.h create mode 100755 decarta/decarta_config.c create mode 100755 decarta/decarta_config.h create mode 100755 decarta/decarta_directory.c create mode 100755 decarta/decarta_directory.h create mode 100644 decarta/decarta_geocode.c create mode 100644 decarta/decarta_geocode.h create mode 100644 decarta/decarta_log.h create mode 100755 decarta/decarta_maps.c create mode 100644 decarta/decarta_maps.h create mode 100755 decarta/decarta_route.c create mode 100755 decarta/decarta_route.h create mode 100755 decarta/decarta_types.c create mode 100755 decarta/decarta_types.h create mode 100755 decarta/decarta_xml.h create mode 100755 decarta/decarta_xml_directory.c create mode 100755 decarta/decarta_xml_geocode.c create mode 100755 decarta/decarta_xml_internal.c create mode 100755 decarta/decarta_xml_internal.h create mode 100755 decarta/decarta_xml_maps.c create mode 100755 decarta/decarta_xml_route.c create mode 100755 decarta/http_wrapper.c create mode 100644 decarta/http_wrapper.h create mode 100755 decarta/xml_wrapper.c create mode 100755 decarta/xml_wrapper.h create mode 100644 elm_module/Makefile.am create mode 100755 elm_module/decarta.c create mode 100755 location_module/Makefile.am create mode 100755 location_module/location_decarta.c create mode 100644 location_module/location_decarta.h create mode 100755 packaging/libdecarta.spec create mode 100644 tests/Makefile.am create mode 100755 tests/decarta_test.c diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..bbe9d02 --- /dev/null +++ b/LICENSE @@ -0,0 +1,206 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..ef0197c --- /dev/null +++ b/Makefile.am @@ -0,0 +1,6 @@ +ACLOCAL_AMFLAGS=-I m4 + +SUBDIRS= crypt decarta elm_module location_module + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = decarta.pc diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..e6f3a78 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,21 @@ +#!/bin/sh +rm -f config.cache +rm -f acconfig.h + +echo "- libtoolize..." +libtoolize --force || exit $? + +echo "- aclocal..." +aclocal --force -I m4 || exit $? + +echo "- autoheader..." +autoheader --force || exit $? + +echo "- automake..." +automake --add-missing --force-missing || exit $? + +echo "- autoconf..." +autoconf --force || exit $? + +echo "- ready!" +exit diff --git a/configure.ac b/configure.ac new file mode 100755 index 0000000..d8e8535 --- /dev/null +++ b/configure.ac @@ -0,0 +1,147 @@ +# Initialize +AC_PREREQ(2.61) +AC_INIT(Decarta, 0.1, [sangho.g.park@samsung.com]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADER([config.h]) +AC_CONFIG_SRCDIR([decarta/decarta_config.c]) +AM_INIT_AUTOMAKE([1.10.2 foreign -Wall]) + +# Check programs for making executable +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_INSTALL + +# Check programs for making libraries. +AM_PROG_LIBTOOL + +# Check host system +m4_define([v_maj], [0]) +m4_define([v_min], [7]) +m4_define([v_mic], [0]) +AC_CANONICAL_HOST +case "$host_os" in + mingw32ce* | cegcc*) + MODULE_ARCH="$host_os-$host_cpu" + ;; + *) + MODULE_ARCH="$host_os-$host_cpu-v_maj.v_min.v_mic" + ;; +esac +AC_SUBST(MODULE_ARCH) +AC_DEFINE_UNQUOTED(MODULE_ARCH, "$MODULE_ARCH", "Module architecture") + +# Add default build options to CFLAGS, LDFLAGS +if test "x$GCC" = "xyes"; then + CFLAGS="$CFLAGS -Wall" + LDFLAGS="$LDFLAGS -Wl,-z,defs -Wl,--as-needed -Wl,--hash-style=both" +fi + +# Add -g option to CFLAGS +AC_ARG_ENABLE([debug], + [AC_HELP_STRING([--enable-debug],[turn on debugging [default=no]])], + [case "${enableval}" in + yes) enable_dbg=yes ;; + no) enable_dbg=no ;; + *) AC_MSG_ERROR([Bad value ${enableval} for --enable-debug]) ;; + esac],[enable_dbg=no]) +if ([test "x$enable_dbg" = xyes]); then + CFLAGS="$CFLAGS -g" +fi + +# Check GCC EFL visibility +AC_MSG_CHECKING(for ELF visibility) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + __attribute__((visibility("default"))) + int var=10; + ]])], + [has_visibility=yes + AC_DEFINE([EXPORT_API], [__attribute__((visibility("default")))], [Symbol visibility prefix]) + CFLAGS="$CFLAGS -fvisibility=hidden"], + [has_visibility=no + AC_DEFINE([EXPORT_API], [], [Symbol visibility prefix]) ] +) +AC_MSG_RESULT($has_visibility) + +# Checks libraries +PKG_CHECK_MODULES(DOCRYPT, [glib-2.0]) +AC_SUBST(DOCRYPT_LIBS) +AC_SUBST(DOCRYPT_CFLAGS) + +AC_CHECK_HEADERS([gcrypt.h]) +PKG_CHECK_MODULES(CRYPT, [glib-2.0]) +AC_SUBST(CRYPT_LIBS) +AC_SUBST(CRYPT_CFLAGS) +AC_SEARCH_LIBS([gcry_cipher_open],[gcrypt],[CRYPT_LIBS="$CRYPT_LIBS -lgcrypt"]) +AC_SEARCH_LIBS([gpg_strerror],[gpg-error],[CRYPT_LIBS="$CRYPT_LIBS -lgpg-error"]) + +PKG_CHECK_MODULES(DECARTA, [glib-2.0 libsoup-2.4 libxml-2.0 gconf-2.0]) +AC_SUBST(DECARTA_LIBS) +AC_SUBST(DECARTA_CFLAGS) + +PKG_CHECK_MODULES(LOCATION_MOD, [glib-2.0 gmodule-2.0 vconf location]) +AC_SUBST(LOCATION_MOD_LIBS) +AC_SUBST(LOCATION_MOD_CFLAGS) + +PKG_CHECK_MODULES(ELM_MOD, [glib-2.0 elementary]) +AC_SUBST(ELM_MOD_LIBS) +AC_SUBST(ELM_MOD_CFLAGS) + +PKG_CHECK_MODULES(TEST, [glib-2.0 gconf-2.0 location]) +AC_SUBST(TEST_LIBS) +AC_SUBST(TEST_CFLAGS) + +# Check dlog libraris +AC_ARG_ENABLE([dlog], + [AC_HELP_STRING([--enable-dlog],[show dlog message [default=no]])], + [case "${enableval}" in + yes) enable_dlog=yes ;; + no) enable_dlog=no ;; + *) AC_MSG_ERROR([Bad value ${enableval} for --enable-dlog]) ;; + esac],[enable_dlog=no]) +if ([test "x$enable_dlog" = xyes]); then + PKG_CHECK_MODULES(DLOG, [dlog], have_dlog="yes", have_dlog="no") + AC_SUBST(DLOG_LIBS) + AC_SUBST(DLOG_CFLAGS) + if test "x$have_dlog" = "xyes"; then + DECARTA_CFLAGS="$DECARTA_CFLAGS -DDECARTA_DLOG_DEBUG $DLOG_CFLAGS" + DECARTA_LIBS="$DECARTA_LIBS $DLOG_LIBS" + LOCATION_MOD_CFLAGS="$LOCATION_MOD_CFLAGS -DDECARTA_DLOG_DEBUG $DLOG_CFLAGS" + LOCATION_MOD_LIBS="$LOCATION_MOD_LIBS $DLOG_LIBS" + fi +fi + +# Check application path for installing configuration file +if ([test "x$APP_DIR" = x]); then + AC_DEFINE([APP_PATH],["/opt/apps"], [application path for reading conf file]) +else + AC_DEFINE_UNQUOTED([APP_PATH],["$APP_DIR"], [application path for reading conf file]) +fi + +if ([test "x$APP_CONF_DIR" = x]); then + AC_DEFINE([APP_CONF_PATH],["res/.decarta"], [application path for reading conf file]) +else + AC_DEFINE_UNQUOTED([APP_CONF_PATH],["$APP_CONF_DIR"], [application path for reading conf file]) +fi + +if ([test "x$DEF_CONF_DIR" = x]); then + AC_DEFINE([DEF_CONF_PATH],["/etc/decarta"], [default application path for reading conf file]) +else + AC_DEFINE_UNQUOTED([DEF_CONF_PATH],["$DEF_CONF_DIR"], [default application path for reading conf file]) +fi +DEF_CONF_PATH="$DEF_CONF_DIR" +AC_SUBST(DEF_CONF_PATH) + +# Generate files +AC_CONFIG_FILES([ +decarta.pc +Makefile +crypt/Makefile +decarta/Makefile +elm_module/Makefile +location_module/Makefile +tests/Makefile +]) + +AC_OUTPUT diff --git a/crypt/Makefile.am b/crypt/Makefile.am new file mode 100644 index 0000000..12529a1 --- /dev/null +++ b/crypt/Makefile.am @@ -0,0 +1,21 @@ +noinst_LTLIBRARIES = libcryption.la +libcryption_la_SOURCES =\ + cryption.c\ + cryption.h +libcryption_la_CFLAGS =\ + -fPIC\ + $(CRYPT_CFLAGS) +libcryption_la_LIBADD =\ + $(CRYPT_LIBS) + +bin_PROGRAMS = docrypt +docrypt_SOURCES = \ + docrypt.c +docrypt_CFLAGS = \ + $(DOCRYPT_CFLAGS) + +docrypt_DEPENDENCIES =\ + libcryption.la +docrypt_LDADD = \ + $(docrypt_DEPENDENCIES)\ + $(DOCRYPT_LIBS) diff --git a/crypt/conf.org b/crypt/conf.org new file mode 100644 index 0000000..2eceb1d --- /dev/null +++ b/crypt/conf.org @@ -0,0 +1,6 @@ +CLIENT_NAME=guest; +CLIENT_PASSWORD=guest; +CONFIGURATION=global-mobile; +HOST=http://ws.decarta.com/openls/openls; + + diff --git a/crypt/cryption.c b/crypt/cryption.c new file mode 100644 index 0000000..16f8a28 --- /dev/null +++ b/crypt/cryption.c @@ -0,0 +1,231 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#include +#include +#include +#include "cryption.h" + +#define BUF_LEN 1024 +#define CIPHER_ALGORITHM GCRY_CIPHER_BLOWFISH +#define CIPHER_MODE GCRY_CIPHER_MODE_ECB + +static char* key_string = "SamsungDecarta"; + +static void * +string2hex (const char *string, + size_t *buff_len) +{ + g_return_val_if_fail (string, NULL); + g_return_val_if_fail (buff_len, NULL); + + *buff_len = g_utf8_strlen(string, -1)*2+1; + unsigned char *buffer = g_malloc0_n (*buff_len, sizeof(unsigned char*)); + unsigned int idx = 0; + for (idx = 0; idx < *buff_len; idx+=2) { + char temp[3]; + if (!g_ascii_isalnum(string[idx/2])) { + break; + } + g_snprintf (temp, 3, "%x", (unsigned int)string[idx/2]); + buffer[idx] = temp[0]; + buffer[idx+1] = temp[1]; + } + buffer[*buff_len-1] = '\0'; + return buffer; +} + +static gboolean +encrypt_decrypt (gboolean is_encrypt, + const void *iv_buf, size_t iv_buflen, + const void *key_buf, size_t key_buflen, + const void *inbuf, size_t inbuf_len, + void *outbuf, size_t *outbuf_len) +{ + g_return_val_if_fail (key_buf, FALSE); + g_return_val_if_fail (inbuf, FALSE); + g_return_val_if_fail (outbuf, FALSE); + g_return_val_if_fail (outbuf_len, FALSE); + + gpg_error_t err; + gcry_cipher_hd_t hd; + void *outblock = NULL; + size_t blocklen; + void *inblock = NULL; + gboolean ret = TRUE; + + err = gcry_cipher_open (&hd, CIPHER_ALGORITHM, CIPHER_MODE, 0); + if (err) { + g_warning ("fail to gcry_cipher_open: %s\n", gpg_strerror (err)); + return FALSE; + } + + blocklen = gcry_cipher_get_algo_blklen (CIPHER_ALGORITHM); + + gcry_cipher_ctl (hd, 61, NULL, 0); + err = gcry_cipher_setkey (hd, key_buf, key_buflen); + if (err) { + g_warning ("fail to gcry_cipher_setkey: %s\n", gpg_strerror (err)); + return FALSE; + } + + if (CIPHER_MODE != GCRY_CIPHER_MODE_ECB) + { + if(!iv_buf|| iv_buflen == 0) return FALSE; + err = gcry_cipher_setiv (hd, iv_buf, iv_buflen); + if (err) { + g_warning ("fail to gcry_cipher_setiv: %s\n", gpg_strerror (err)); + return FALSE; + } + } + + inblock = gcry_xmalloc (blocklen); + outblock = gcry_xmalloc (blocklen); + int idx =0 ; + while (idx < inbuf_len) { + size_t len = ((inbuf_len - idx)= 0) close(outfd); + if (infd >= 0) close(infd); + + return ret; +} + +char* +do_decryption (const char *filename) +{ + g_return_val_if_fail (filename, NULL); + + char *ret = NULL; + size_t key_buflen; + void *keybuf = NULL; + char inbuf[BUF_LEN]; + char outbuf[BUF_LEN]; + size_t inlen = 0; + size_t outlen = 0; + int infd = -1; + + memset (inbuf, 0, BUF_LEN); + memset (outbuf, 0, BUF_LEN); + + if ((infd = open(filename, O_RDONLY)) < 0) { + g_warning ("open(%s) failed", filename); + } else { + if ((inlen = read(infd, inbuf, BUF_LEN)) <= 0) { + g_warning ("read(%d) failed", infd); + } else { + if ((keybuf = string2hex (key_string, &key_buflen)) && inbuf != NULL) { + if (encrypt_decrypt (FALSE, NULL, 0, keybuf, key_buflen, (void*)inbuf, inlen, (void*)outbuf, &outlen)) { + ret = g_strdup (outbuf); + } else { + g_warning ("encrypt_decrypt failed"); + } + } else { + g_warning ("string2hex failed"); + } + } + } + + if (keybuf) gcry_free (keybuf); + if (infd >= 0) close(infd); + + return ret; +} diff --git a/crypt/cryption.h b/crypt/cryption.h new file mode 100644 index 0000000..0fd8e17 --- /dev/null +++ b/crypt/cryption.h @@ -0,0 +1,36 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _CRYPTION_H_ +#define _CRYPTION_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +char* do_decryption(const char *filename); +int do_encryption(const char *filename); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypt/docrypt.c b/crypt/docrypt.c new file mode 100644 index 0000000..ee1c9cd --- /dev/null +++ b/crypt/docrypt.c @@ -0,0 +1,72 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#include +#include +#include "cryption.h" + +#define FILENAME_SIZE 1024 + +void print_options (void) +{ + printf ("USAGE: docrypt [options] [filename]\n"); + printf ("size of [filename] is smaller than 1024\n"); + printf ("Options:\n\t-e\tEncrypt\n\t-d\tDecrypt\n"); +} + +int main(int argc, char* argv[]) +{ + if (argc != 3 || !argv) { + print_options(); + return -1; + } + if (0 == strcmp(argv[1], "-e")) { + if (strlen(argv[2]) <= FILENAME_SIZE) { + if(!do_encryption(argv[2])) { + g_warning ("Encryption Failed"); + return -1; + } + g_debug ("Encryption Success"); + } else { + print_options(); + return -1; + } + } else if (0 == strcmp(argv[1], "-d")) { + char *buf = NULL; + if (strlen(argv[2]) <= FILENAME_SIZE) { + if(!(buf = do_decryption(argv[2]))) { + g_warning ("Decryption Failed"); + return -1; + } + g_debug ("Decryption Success!!"); + g_printf ("%s\n", buf); + } else { + print_options(); + return -1; + } + } else { + print_options(); + return -1; + } + return 0; +} diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..ad727a4 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,449 @@ +libdecarta (0.2.7-17) unstable; urgency=low + + * Make a dir before creating a link file. + * Tag: libdecarta_0.2.7-17 + + -- Minjune Kim Mon, 20 Aug 2012 21:09:16 +0900 + +libdecarta (0.2.7-16) unstable; urgency=low + + * Change the name of library. + * Tag: libdecarta_0.2.7-16 + + -- Minjune Kim Thu, 09 Aug 2012 20:16:12 +0900 + +libdecarta (0.2.7-15) unstable; urgency=low + + * [Bug] multi geocoder crash. postion_cb()'s accuracy should be copied before append + * Tag: libdecarta_0.2.7-15 + + -- Minjune Kim Wed, 08 Aug 2012 10:53:25 +0900 + +libdecarta (0.2.7-14) unstable; urgency=low + + * Seperate map service from location service + * Tag: libdecarta_0.2.7-14 + + -- Minjune Kim Wed, 25 Jul 2012 16:04:43 +0900 + +libdecarta (0.2.7-13) unstable; urgency=low + + * Add break as a workaround when asynchronously calling geocode. + * Tag: libdecarta_0.2.7-13 + + -- Minjune Kim Tue, 24 Jul 2012 17:54:46 +0900 + +libdecarta (0.2.7-12) unstable; urgency=low + + * fix route no geometry in segment, wrong position, cancel and plugin for elm_map + * Support packages having name as 'org.tizen.' + * Tag: libdecarta_0.2.7-12 + + -- Minjune Kim Fri, 13 Jul 2012 19:18:31 +0900 + +libdecarta (0.2.7-11) unstable; urgency=low + + * Fix http_proxy problem + * Tag: libdecarta_0.2.7-11 + + -- Youngae Kang Fri, 06 Jul 2012 17:35:09 +0900 + +libdecarta (0.2.7-10) unstable; urgency=low + + * Return Error when there is no request for a route on queue. + * Tag: libdecarta_0.2.7-10 + + -- Minjune Kim Wed, 04 Jul 2012 19:11:40 +0900 + +libdecarta (0.2.7-9) unstable; urgency=low + + * Change distance unit from MI to M. + * Tag: libdecarta_0.2.7-9 + + -- Minjune Kim Mon, 02 Jul 2012 19:44:45 +0900 + +libdecarta (0.2.7-8) unstable; urgency=low + + * FIXED: Support sortCriteria for POI TC. + * Tag: libdecarta_0.2.7-8 + + -- Minjune Kim Mon, 23 Apr 2012 17:43:35 +0900 + +libdecarta (0.2.7-7) unstable; urgency=low + + * TMP. Do not use sortCriteria for POI TC. + * Tag: libdecarta_0.2.7-7 + + -- Minjune Kim Thu, 12 Apr 2012 20:22:42 +0900 + +libdecarta (0.2.7-6) unstable; urgency=low + + * 1. deliver req_id in callback even if search failed. 2. Not to return error even if sort item is NULL. + * Tag: libdecarta_0.2.7-6 + + -- Youngae Kang Fri, 16 Mar 2012 19:07:23 +0900 + +libdecarta (0.2.7-5) unstable; urgency=low + + * Support Capability + * Tag: libdecarta_0.2.7-5 + + -- Genie Kim Wed, 14 Mar 2012 20:41:17 +0900 + +libdecarta (0.2.7-4) unstable; urgency=low + + * call async request in idle callback to avoid the first request missing + * Tag: libdecarta_0.2.7-4 + + -- Minjune Kim Mon, 12 Mar 2012 20:22:48 +0900 + +libdecarta (0.2.7-3) unstable; urgency=low + + * Workaroud : Give the first element of geocode_list to a caller in position_cb because of crash + * Tag: libdecarta_0.2.7-3 + + -- Minjune Kim Fri, 09 Mar 2012 17:11:05 +0900 + +libdecarta (0.2.7-2) unstable; urgency=low + + * NOT_FOUND_ERROR added, memory leak modified + * Tag: libdecarta_0.2.7-2 + + -- Minjune Kim Wed, 07 Mar 2012 22:02:18 +0900 + +libdecarta (0.2.7-1) unstable; urgency=low + + * Implemented POI & Route + * Tag: libdecarta_0.2.7-1 + + -- Genie Kim Tue, 28 Feb 2012 23:55:46 +0900 + +libdecarta (0.2.6-2) unstable; urgency=low + + * New ClientName & PWD. Add new maintainer + * Tag: libdecarta_0.2.6-2 + + -- Minjune Kim Tue, 14 Feb 2012 11:18:13 +0900 + +libdecarta (0.2.6-1) unstable; urgency=low + + * support the multi geocode result + * Tag: libdecarta_0.2.6-1 + + -- Minjune Kim Thu, 09 Feb 2012 10:04:18 +0900 + +libdecarta (0.2.5-6) unstable; urgency=low + + * Remove docrypt package + * Tag: libdecarta_0.2.5-6 + + -- Yunhan Kim Wed, 30 Nov 2011 16:03:10 +0900 + +libdecarta (0.2.5-5) unstable; urgency=low + + * Remove stderr on/off function. + * Tag: libdecarta_0.2.5-5 + + -- Yunhan Kim Mon, 07 Nov 2011 15:59:37 +0900 + +libdecarta (0.2.5-4) unstable; urgency=low + + * Change country code that comes from locale. + * Tag: libdecarta_0.2.5-4 + + -- Yunhan Kim Thu, 03 Nov 2011 21:27:09 +0900 + +libdecarta (0.2.5-3) unstable; urgency=low + + * Distinguish between network error and XML error. + * Tag: libdecarta_0.2.5-3 + + -- Yunhan Kim Mon, 31 Oct 2011 16:46:17 +0900 + +libdecarta (0.2.5-2) unstable; urgency=low + + * Fix up a bug while cancel http requests + * Fix up rejecting non-ascii characters on parsing xml. + * Tag: libdecarta_0.2.5-2 + + -- Yunhan Kim Fri, 21 Oct 2011 13:27:29 +0900 + +libdecarta (0.2.5-1) unstable; urgency=low + + * Cancel all asynchronous http requests when the module is unloaded. + * Tag: libdecarta_0.2.5-1 + + -- Yunhan Kim Fri, 21 Oct 2011 08:59:50 +0900 + +libdecarta (0.2.4-1) unstable; urgency=low + + * fixed prevent defect + * Tag: libdecarta_0.2.4-1 + + -- Genie Kim Fri, 26 Aug 2011 13:44:00 +0900 + +libdecarta (0.2.3-2) unstable; urgency=low + + * fix build break for i386 + * Tag: libdecarta_0.2.3-2 + + -- Genie Kim Fri, 12 Aug 2011 16:33:46 +0900 + +libdecarta (0.2.3-1) unstable; urgency=low + + * remove inhouse account + * Tag: libdecarta_0.2.3-1 + + -- Genie Kim Fri, 12 Aug 2011 11:43:07 +0900 + +libdecarta (0.2.3) unstable; urgency=low + + * Refresh decarta map after all sources URL are loaded + * Tag: libdecarta_0.2.3 + + -- Tae-Hwan Kim Mon, 16 May 2011 16:08:47 +0900 + +libdecarta (0.2.2) unstable; urgency=low + + * Remove callbacks before unloading modules and request async APIs + * Tag: libdecarta_0.2.2 + + -- Tae-Hwan Kim Fri, 13 May 2011 19:32:55 +0900 + +libdecarta (0.2.1) unstable; urgency=low + + * Fix for elm map API change + * Tag: libdecarta_0.2.1 + + -- Tae-Hwan Kim Thu, 12 May 2011 20:07:40 +0900 + +libdecarta (0.2.0) unstable; urgency=low + + * Release New decarta APIs + * Tag: libdecarta_0.2.0 + + -- Tae-Hwan Kim Wed, 27 Apr 2011 19:50:01 +0900 + +libdecarta (0.1.24-1) unstable; urgency=low + + * Apply New Location APIs + * Tag: libdecarta_0.1.24-1 + + -- Tae-Hwan Kim Wed, 20 Apr 2011 11:19:09 +0900 + +libdecarta (0.1.23-1) unstable; urgency=low + + * Fix for sbox1 i386 (It should be removed later) + * Tag: libdecarta_0.1.23-1 + + -- Tae-Hwan Kim Wed, 16 Mar 2011 16:49:59 +0900 + +libdecarta (0.1.22-1) unstable; urgency=low + + * Fix memory leak/Depend. & Apply prevent + * Tag: libdecarta_0.1.22-1 + + -- Tae-Hwan Kim Sat, 12 Feb 2011 12:00:21 +0900 + +libdecarta (0.1.21-1) unstable; urgency=low + + * Apply prevent + * Tag: libdecarta_0.1.21-1 + + -- Tae-Hwan Kim Thu, 27 Jan 2011 10:20:53 +0900 + +libdecarta (0.1.20-2) unstable; urgency=low + + * Fix build dependency + * Tag: libdecarta_0.1.20-2 + + -- Tae-Hwan Kim Thu, 20 Jan 2011 12:15:56 +0900 + +libdecarta (0.1.20-1) unstable; urgency=low + + * Add async geocode API & Split package & Chnage conf path + * Tag: libdecarta_0.1.20-1 + + -- Tae-Hwan Kim Thu, 20 Jan 2011 09:59:52 +0900 + +libdecarta (0.1.19-1) unstable; urgency=low + + * non-blocking map & Add landmark module + * Tag: libdecarta_0.1.19-1 + + -- Taehwan kim Thu, 06 Jan 2011 10:13:07 +0900 + +libdecarta (0.1.18-1) unstable; urgency=low + + * Adapt to plugin change & Fix http bug + * Tag: libdecarta_0.1.18-1 + + -- Taehwan kim Tue, 21 Dec 2010 17:44:43 +0900 + +libdecarta (0.1.17-0) unstable; urgency=low + + * Adap to plugin change & refine route APIs + * Tag: libdecarta_0.1.17-0 + + -- Taehwan kim Mon, 13 Dec 2010 10:03:15 +0900 + +libdecarta (0.1.16-0) unstable; urgency=low + + * Fix http bug & app exit bug + * Tag: libdecarta_0.1.16-0 + + -- Taehwan kim Thu, 02 Dec 2010 13:25:44 +0900 + +libdecarta (0.1.15-0) unstable; urgency=low + + * Add map async API & Fix http bugs + * Tag: libdecarta_0.1.15-0 + + -- Taehwan kim Mon, 29 Nov 2010 11:21:18 +0900 + +libdecarta (0.1.14-0) unstable; urgency=low + + * Tweak decarta & apply to location/elm module + * Tag: libdecarta_0.1.14-0 + + -- Taehwan kim Wed, 24 Nov 2010 11:16:17 +0900 + +libdecarta (0.1.13-1) unstable; urgency=low + + * Add geoclue-xps + * Tag: libdecarta_0.1.13-1 + + -- Taehwan kim Mon, 08 Nov 2010 22:34:28 +0900 + +libdecarta (0.1.12-1) unstable; urgency=low + + * Add encrypt package + * Tag: libdecarta_0.1.12-1 + + -- Taehwan kim Sun, 31 Oct 2010 16:08:52 +0900 + +libdecarta (0.1.11-1) unstable; urgency=low + + * Add get appname in gtk + * Tag: libdecarta_0.1.11-1 + + -- Taehwan kim Thu, 28 Oct 2010 16:17:39 +0900 + +libdecarta (0.1.10-1) unstable; urgency=low + + * Change account loading path. + * Tag: libdecarta_0.1.10-1 + + -- Taehwan kim Wed, 27 Oct 2010 21:41:14 +0900 + +libdecarta (0.1.9-1) unstable; urgency=low + + * Add stderr on/off func. + * Tag: libdecarta_0.1.9-1 + + -- Taehwan kim Wed, 27 Oct 2010 13:24:03 +0900 + +libdecarta (0.1.8-1) unstable; urgency=low + + * Change Home dir. /usr/home --> /opt/home + * Tag: libdecarta_0.1.8-1 + + -- Taehwan kim Fri, 22 Oct 2010 13:38:10 +0900 + +libdecarta (0.1.7-1) unstable; urgency=low + + * fix session timeout + * Tag: libdecarta_0.1.7-1 + + -- Taehwan kim Fri, 22 Oct 2010 10:40:06 +0900 + +libdecarta (0.1.6-1) unstable; urgency=low + + * temporary use fixed session ID + * Tag: libdecarta_0.1.6-1 + + -- Taehwan kim Thu, 21 Oct 2010 17:02:16 +0900 + +libdecarta (0.1.5-1) unstable; urgency=low + + * Fix BS + * Tag: libdecarta_0.1.5-1 + + -- Taehwan kim Thu, 21 Oct 2010 15:45:15 +0900 + +libdecarta (0.1.4-1) unstable; urgency=low + + * Apply authentication + * Tag: libdecarta_0.1.4-1 + + -- Taehwan kim Thu, 21 Oct 2010 14:56:38 +0900 + +libdecarta (0.1.3-1) unstable; urgency=low + + * optimize map loading time + * Tag: libdecarta_0.1.3-1 + + -- Taehwan kim Thu, 21 Oct 2010 11:41:39 +0900 + +libdecarta (0.1.2-1) unstable; urgency=low + + * fix unproject func. + * Tag: libdecarta_0.1.2-1 + + -- Taehwan kim Wed, 20 Oct 2010 17:07:55 +0900 + +libdecarta (0.1.1-7) unstable; urgency=low + + * Home dir: $HOME --> /usr/home/root & Account: global --> kr + * Tag: libdecarta_0.1.1-7 + + -- Taehwan kim Tue, 19 Oct 2010 15:38:45 +0900 + +libdecarta (0.1.1-6) unstable; urgency=low + + * if no proxy in gconf, do not set proxy in libsoup + * Tag: libdecarta_0.1.1-6 + + -- Taehwan kim Fri, 15 Oct 2010 11:07:36 +0900 + +libdecarta (0.1.1-5) unstable; urgency=low + + * Add gconf loading & libsoup setting temporarily + * Tag: libdecarta_0.1.1-5 + + -- Taehwan kim Thu, 14 Oct 2010 16:41:27 +0900 + +libdecarta (0.1.1-4) unstable; urgency=low + + * Fix for new build system + * Tag: libdecarta_0.1.1-4 + + -- Taehwan kim Thu, 14 Oct 2010 08:59:55 +0900 + +libdecarta (0.1.1-3) unstable; urgency=low + + * Remove proxy setting & Change num. of http con. 32 --> 128 + * Tag: libdecarta_0.1.1-3 + + -- Taehwan kim Wed, 13 Oct 2010 18:14:51 +0900 + +libdecarta (0.1.1-2) unstable; urgency=low + + * Remove proxy setting in libsoup + * Tag: libdecarta_0.1.1-2 + + -- Taehwan kim Tue, 12 Oct 2010 20:32:12 +0900 + +libdecarta (0.1.1-1) unstable; urgency=low + + * change install to install.in + * Tag: libdecarta_0.1.1-1 + + -- Sangho Park Tue, 12 Oct 2010 10:41:02 +0900 + +libdecarta (0.1.0) unstable; urgency=low + + * Initial version + * Tag: libdecarta_0.1.0 + + -- Tae-hwan Kim Mon, 30 Aug 2010 12:01:05 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..022315c --- /dev/null +++ b/debian/control @@ -0,0 +1,42 @@ +Source: libdecarta +Section: libs +Priority: extra +Maintainer: Youngae Kang , Yunhan Kim , Genie kim , Minjune Kim , Ming Zhu +Uploaders: Yunhan Kim +Build-Depends: debhelper (>= 5), libglib2.0-dev, dlog-dev, libsoup2.4-dev, libgcrypt11-dev, libelm-dev, libxml2-dev, libgconf-dbus-dev, libvconf-dev, libslp-location-dev +Standards-Version: 3.7.2 + +Package: libdecarta +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Decarta Web Service Library (Shared Object) + Decarta Web Service Library + +Package: libdecarta-dev +Section: libdevel +Architecture: any +XB-Generate-Docs: no +XB-Public-Package: no +Depends: ${shlibs:Depends}, ${misc:Depends}, libdecarta (= ${binary:Version}), libglib2.0-dev +Description: Decarta Web Service Library (Development Headers) + Decarta Web Service Library Development Package + +Package: libdecarta-dbg +Section: debug +Architecture: any +Depends: ${misc:Depends}, libdecarta(=${binary:Version}) +Description: Decarta Web Service Library (unstripped) + Decarta Web Service Library Debug Package + +Package: elementary-decarta +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdecarta(=${binary:Version}) +Description: elementary map module for decarta + +Package: location-decarta +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libdecarta(=${binary:Version}) +Description: location geocode module for decarta diff --git a/debian/elementary-decarta.install.in b/debian/elementary-decarta.install.in new file mode 100644 index 0000000..88d26f0 --- /dev/null +++ b/debian/elementary-decarta.install.in @@ -0,0 +1 @@ +@PREFIX@/lib/elementary/modules/decarta-normal/*/*.so* diff --git a/debian/libdecarta-dev.install.in b/debian/libdecarta-dev.install.in new file mode 100644 index 0000000..d59062e --- /dev/null +++ b/debian/libdecarta-dev.install.in @@ -0,0 +1,3 @@ +@PREFIX@/include/* +@PREFIX@/lib/pkgconfig/* +@PREFIX@/lib/*.la diff --git a/debian/libdecarta.install.in b/debian/libdecarta.install.in new file mode 100644 index 0000000..7b47e5d --- /dev/null +++ b/debian/libdecarta.install.in @@ -0,0 +1,2 @@ +@PREFIX@/lib/*.so* +@DEF_CONF_DIR@/*.enc diff --git a/debian/libdecarta.postinst b/debian/libdecarta.postinst new file mode 100644 index 0000000..4575c2f --- /dev/null +++ b/debian/libdecarta.postinst @@ -0,0 +1,7 @@ +#!/bin/sh + +#if [ "${USER}" = "root" ] +#then +# chown inhouse:inhouse /opt/data/decarta/*.enc +# chmod 444 /opt/data/decarta/*.enc +#fi diff --git a/debian/location-decarta.install.in b/debian/location-decarta.install.in new file mode 100644 index 0000000..f99d979 --- /dev/null +++ b/debian/location-decarta.install.in @@ -0,0 +1 @@ +@PREFIX@/lib/location/module/*.so* diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..a48dfca --- /dev/null +++ b/debian/rules @@ -0,0 +1,120 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt +DEF_CONF_DIR ?= /etc/decarta + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 + CXXFLAGS += -O0 +else + CFLAGS += -O2 + CXXFLAGS += -O2 +endif + +configure: configure-stamp +configure-stamp: + dh_testdir + ./autogen.sh + # Add here commands to configure the package. + ./configure --prefix=/usr --enable-dlog --enable-debug APP_DIR=/opt/apps APP_CONF_DIR=res/.decarta DEF_CONF_DIR="$(DEF_CONF_DIR)" + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + sed -i -e "s#@DEF_CONF_DIR@#$(DEF_CONF_DIR)#g" $${f%.in}; \ + done + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + - $(MAKE) clean + - $(MAKE) distclean + + rm -rf CMakeCache.txt + rm -rf CMakeFiles + rm -rf cmake_install.cmake + rm -rf Makefile + rm -rf install_manifest.txt + rm -rf *.so + rm -f pkgconfig/decarta.pc + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/wavplayer. + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs +# dh_installdocs + dh_installexamples + dh_install --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link +# dh_strip + dh_strip --dbg-package=libdecarta-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/decarta.pc.in b/decarta.pc.in new file mode 100644 index 0000000..d585588 --- /dev/null +++ b/decarta.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +datarootdir = @datarootdir@ +datadir=@datadir@ + +Name: decarta +Description: decarta library +Requires: glib-2.0 +Version: @VERSION@ +Libs: -L${libdir} -ldecarta +Cflags: -I${includedir} -I${includedir}/decarta diff --git a/decarta/Makefile.am b/decarta/Makefile.am new file mode 100644 index 0000000..8a0f60f --- /dev/null +++ b/decarta/Makefile.am @@ -0,0 +1,48 @@ +dir_crypt = $(top_srcdir)/crypt + +lib_LTLIBRARIES = libdecarta.la + +libdecarta_la_SOURCES = \ + http_wrapper.c \ + http_wrapper.h \ + xml_wrapper.c \ + xml_wrapper.h \ + decarta_xml_internal.c\ + decarta_xml_internal.h \ + decarta_xml_maps.c \ + decarta_xml_geocode.c \ + decarta_xml_directory.c \ + decarta_xml_route.c \ + decarta_xml.h \ + decarta_types.h\ + decarta_types.c\ + decarta_geocode.c\ + decarta_geocode.h\ + decarta_directory.c\ + decarta_directory.h\ + decarta_route.c\ + decarta_route.h\ + decarta_maps.c\ + decarta_maps.h\ + decarta_config.c\ + decarta_config.h\ + decarta.h + +libdecarta_la_CFLAGS = \ + -fPIC\ + -I$(dir_crypt)\ + $(DECARTA_CFLAGS) +libdecarta_la_DEPENDENCIES =\ + $(dir_crypt)/libcryption.la +libdecarta_la_LIBADD = \ + $(libdecarta_la_DEPENDENCIES)\ + $(DECARTA_LIBS) + +libdecarta_includedir = $(includedir)/decarta +libdecarta_include_HEADERS = \ + decarta.h\ + decarta_types.h\ + decarta_geocode.h\ + decarta_directory.h\ + decarta_route.h\ + decarta_maps.h diff --git a/decarta/decarta.h b/decarta/decarta.h new file mode 100644 index 0000000..ef8d4df --- /dev/null +++ b/decarta/decarta.h @@ -0,0 +1,32 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_H_ +#define _DECARTA_H_ + +#include +#include +#include +#include +#include +#include + +#endif diff --git a/decarta/decarta_config.c b/decarta/decarta_config.c new file mode 100755 index 0000000..d5fe5c2 --- /dev/null +++ b/decarta/decarta_config.c @@ -0,0 +1,197 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#include +#include "decarta_config.h" +#include "decarta_log.h" +#include "cryption.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +static gboolean enabled = FALSE; + +char *const INHOUSE_ENC_PATH = DEF_CONF_PATH; + +char *const DEF_PATH = APP_PATH; +char *const ENC_PATH = APP_CONF_PATH; +char *const ENC_FILE = "conf.enc"; + +#define DECARTA_CLIEN_NAME "CLIENT_NAME" +#define DECARTA_CLIEN_PASSWORD "CLIENT_PASSWORD" +#define DECARTA_CONFIGURATION "CONFIGURATION" +#define DECARTA_HOST "HOST" + +#define DECARTA_CLIENT_NAME_LENGTH 128 +#define DECARTA_CLIENT_PASSWORD_LENGTH 128 +#define DECARTA_CONFIGURATION_LENGTH 128 +#define DECARTA_HOST_LENGTH 255 + +typedef struct { + char clientName[DECARTA_CLIENT_NAME_LENGTH]; ///< Client name. + char clientPassword[DECARTA_CLIENT_PASSWORD_LENGTH]; ///< Client password. + char configuration[DECARTA_CONFIGURATION_LENGTH]; ///< Configuration of representing map. + char host[DECARTA_HOST_LENGTH]; ///< Host URL. +} DecartaConfig; + +DecartaConfig decarta_Config; + +static char* +trim_space (char* str) +{ + char *tok = str; + while (*tok == ' ' || *tok == '\t') tok++; + g_stpcpy (str, tok); + tok = str; + while (*tok != ' ' && *tok != '\t' && *tok != '\0') tok++; + *tok='\0'; + return str; +} + +static gboolean +get_tok (char* value, + char* key, + const char* filepath) +{ + g_return_val_if_fail (value, FALSE); + g_return_val_if_fail (key, FALSE); + g_return_val_if_fail (filepath, FALSE); + + char* buf = do_decryption(filepath); + if(!buf) return FALSE; + + gboolean ret = FALSE; + const char *token = ";\n"; + char *tok = strtok(buf, token); + if (TRUE == g_str_has_prefix(tok, key)) { + char* val = g_strrstr(tok, "=")+1; + if (val) { + trim_space(val); + g_stpcpy(value, val); + ret = TRUE; + } else ret = FALSE; + + g_free(buf); + return ret; + } + while (1) { + tok = strtok(NULL, token); + if (!tok) { + ret = FALSE; + break; + } + + if( TRUE == g_str_has_prefix(tok, key)){ + char* val = g_strrstr(tok, "=")+1; + if (val) { + trim_space(val); + g_stpcpy(value, val); + ret = TRUE; + } else ret = FALSE; + break; + } + } + + g_free(buf); + return ret; +} + +static gboolean +load_config_internal (const char* filepath) +{ + char ID[256], passwd[256], conf[256], host[256]; + if (!get_tok(ID, DECARTA_CLIEN_NAME, filepath) || + !get_tok(passwd, DECARTA_CLIEN_PASSWORD, filepath) || + !get_tok(conf, DECARTA_CONFIGURATION, filepath) || + !get_tok(host, DECARTA_HOST, filepath)) + return FALSE; + + g_stpcpy(decarta_Config.clientName, ID); + g_stpcpy(decarta_Config.clientPassword, passwd); + g_stpcpy(decarta_Config.configuration, conf); + g_stpcpy(decarta_Config.host, host); + + return TRUE; +} + +EXPORT_API void +set_config (char *ID, char *passwd, char *conf, char *host) +{ + if (!ID || !passwd) { + return; + } + + g_stpcpy(decarta_Config.clientName, ID); + g_stpcpy(decarta_Config.clientPassword, passwd); + if (conf) { + g_stpcpy(decarta_Config.configuration, conf); + } else { + g_stpcpy(decarta_Config.configuration, "global-mobile"); + } + if (host) { + g_stpcpy(decarta_Config.host, host); + } else { + g_stpcpy(decarta_Config.host, "http://ws.decarta.com/openls/openls"); + } +} + +char* get_ID (void) +{ + return decarta_Config.clientName; +} + +char* get_passwd (void) +{ + return decarta_Config.clientPassword; +} + +char* get_conf (void) +{ + return decarta_Config.configuration; +} + +char* get_host (void) +{ + return decarta_Config.host; +} + +gboolean load_config (void) +{ + if (enabled) return TRUE; + + enabled = TRUE; + char *decarta_file = NULL; + char *envname = getenv("PKG_NAME"); + if (!envname) return FALSE; + decarta_file = g_strdup_printf("%s/%s/%s/%s", DEF_PATH, envname, ENC_PATH, ENC_FILE); + if (!strlen(decarta_Config.clientName) || !strlen(decarta_Config.clientPassword)) { + if (!load_config_internal(decarta_file)) { + DECARTA_LOGW("loading config (%s) is fail", decarta_file); + enabled = FALSE; + } + } + g_free(decarta_file); + + if (enabled) return TRUE; + return FALSE; +} diff --git a/decarta/decarta_config.h b/decarta/decarta_config.h new file mode 100755 index 0000000..9ced908 --- /dev/null +++ b/decarta/decarta_config.h @@ -0,0 +1,38 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_CONFIG_H_ +#define _DECARTA_CONFIG_H_ + +#include + +G_BEGIN_DECLS + +char* get_ID (void); +char* get_passwd (void); +char* get_conf (void); +char* get_host (void); +gboolean load_config (void); +void set_config (char *ID, char *passwd, char *conf, char *host); + +G_END_DECLS + +#endif /*DECARTA_MAP_CONFIG_H_*/ diff --git a/decarta/decarta_directory.c b/decarta/decarta_directory.c new file mode 100755 index 0000000..9c15433 --- /dev/null +++ b/decarta/decarta_directory.c @@ -0,0 +1,271 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "decarta_log.h" +#include "decarta_config.h" +#include "http_wrapper.h" +#include "decarta_xml.h" +#include "decarta_directory.h" + +static GHashTable *http_reqid_hash = NULL; + +typedef struct { + DecartaDirectoryCB callback; + void *userdata; + guint request_id; /**< used to remove from table after success */ +} DecartaDirCBData; + +static gboolean +__directory_del_table_node_cb(gpointer key, + gpointer value, + gpointer user_data) +{ + if (!user_data || !key || !value) { + return false; + } + HttpHandle http_async = NULL; + + http_async = (HttpHandle)value; + char *user_key = (char *)user_data; + char *table_key = (char *)key; + + if (!g_strcmp0(user_key, table_key)) { + DECARTA_LOGD("req_id [%s] http_async [%d] closed!", table_key, http_async); + g_free(table_key); + http_close(http_async); + return true; + } + DECARTA_LOGD("req_id [%s] http_async [%d] not close", table_key, http_async); + return false; +} + + +static void +search_directory_cb (gboolean success, + char *recv_data, + void *user_data) +{ + DECARTA_LOGD("search_directory_cb"); + DecartaDirCBData* cb_data = (DecartaDirCBData*)user_data; + DecartaError err = DECARTA_ERROR_NONE; + gchar *req_id_str = NULL; + GList *poi_list = NULL; + gchar *error_code = NULL; + gchar *error_msg = NULL; + + if (success != TRUE) { + err = DECARTA_ERROR_HTTP; + } else if (!xml_directory_parse(recv_data, &poi_list, &req_id_str, &error_code, &error_msg)) { + if (g_str_has_prefix(error_msg, "POI not found") == TRUE) { + err = DECARTA_ERROR_NOT_FOUND; + } else { + err = DECARTA_ERROR_XML; + } + } + + if (cb_data && cb_data->callback) cb_data->callback (err, req_id_str, poi_list, error_code, error_msg, cb_data->userdata); + + /** remove the success request id from hash table */ + char *request_id_str = g_strdup_printf("%u", cb_data->request_id); + if (http_reqid_hash) { + DECARTA_LOGD("remove the http async after success!"); + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__directory_del_table_node_cb, (gpointer)request_id_str); + if (!g_hash_table_size(http_reqid_hash)) { + g_hash_table_destroy(http_reqid_hash); + http_reqid_hash = NULL; + } + } + if (request_id_str) { + g_free(request_id_str); + } + + if (recv_data) { + g_free(recv_data); + } + if (poi_list) { + decarta_poi_list_free (poi_list); + } + if (req_id_str) { + g_free(req_id_str); + } + if (error_code) { + g_free(error_code); + } + if (error_msg) { + g_free(error_msg); + } + if (cb_data) { + g_free(cb_data); + } +} + +EXPORT_API int +decarta_search_directory (const DecartaDirectoryRequest *dir_request, + GList **poi_list) +{ + DECARTA_LOGD("decarta_search_directory"); + if (!dir_request || !poi_list) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + int err = DECARTA_ERROR_NONE; + char *req = NULL; + char *resp = NULL; + unsigned int size = 0; + gchar *req_id_str = NULL; + gchar *error_code = NULL; + gchar *error_msg = NULL; + if (!xml_directory_request_get(dir_request, &req, &size)) return DECARTA_ERROR_PARAMETER; + HttpHandle http = http_open(HTTP_TYPE_SYNC); + if (http_send(http, req, get_host(), &resp, NULL, NULL)) { + if (!xml_directory_parse(resp, poi_list, &req_id_str, &error_code, &error_msg)) err = DECARTA_ERROR_XML; + } else err = DECARTA_ERROR_HTTP; + + DECARTA_LOGD("decarta_search_directory: req_id %s, error_code %s, error_msg %s", req_id_str, error_code, error_msg); + if (req_id_str) { + g_free(req_id_str); + } + if (error_code) { + g_free(error_code); + } + if (error_msg) { + g_free(error_msg); + } + if (req) { + g_free (req); + } + if (resp) { + g_free (resp); + } + http_close(http); + return err; +} + +EXPORT_API int +decarta_search_directory_async (const DecartaDirectoryRequest *dir_request, + DecartaDirectoryCB callback, + void *userdata) +{ + DECARTA_LOGD("decarta_search_directory_async"); + if (!dir_request || !callback) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + char* req = NULL; + unsigned int size = 0; + DecartaDirCBData* cb_data = g_new0(DecartaDirCBData, 1); + cb_data->callback = callback; + cb_data->userdata = userdata; + cb_data->request_id = dir_request->request_id; + + if(!xml_directory_request_get(dir_request, &req, &size)) { + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_PARAMETER; + } + + char *request_id_str = g_strdup_printf("%u", dir_request->request_id); + if (request_id_str == NULL) { + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_PARAMETER; + } + + HttpHandle http_async = http_open(HTTP_TYPE_ASYNC); + DECARTA_LOGD("decarta_search_directory_async: http %d, req_id %d", http_async, dir_request->request_id); + if (!http_reqid_hash) { + http_reqid_hash = g_hash_table_new(g_str_hash, g_str_equal); + if (http_reqid_hash == NULL) { + if (request_id_str) { + g_free(request_id_str); + } + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + http_close(http_async); + return DECARTA_ERROR_HTTP; + } + g_hash_table_insert(http_reqid_hash, (gpointer)request_id_str, (gpointer)http_async); + DECARTA_LOGD("first insert http [0x%x], req_id [%d]", http_async, dir_request->request_id); + } else { + g_hash_table_insert(http_reqid_hash, (gpointer)request_id_str, (gpointer)http_async); + DECARTA_LOGD("Not the first insert http [0x%x], req_id [%d]", http_async, dir_request->request_id); + } + + if(!http_send(http_async, req, get_host(), NULL, (HttpCallback)search_directory_cb, cb_data)){ + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__directory_del_table_node_cb, (gpointer)request_id_str); + if (!g_hash_table_size(http_reqid_hash)) { + g_hash_table_destroy(http_reqid_hash); + http_reqid_hash = NULL; + } + + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_HTTP; + } + + // cb_data will be freed in callback + if (req) { + g_free(req); + } + return DECARTA_ERROR_NONE; +} + +EXPORT_API void +decarta_search_directory_async_cancel (guint request_id) +{ + DECARTA_LOGD("decarta_search_directory_async_cancel: req_id %d called", request_id); + + if (http_reqid_hash) { + char *request_id_str = g_strdup_printf("%u", request_id); + if (request_id_str == NULL) { + return; + } + + /** cancel the request_id http async request*/ + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__directory_del_table_node_cb, (gpointer)request_id_str); + g_free(request_id_str); + } else { + DECARTA_LOGD("decarta_search_directory_async_cancel: req_id %d http_reqid_hash NOT exist!", request_id); + } +} diff --git a/decarta/decarta_directory.h b/decarta/decarta_directory.h new file mode 100755 index 0000000..59317bc --- /dev/null +++ b/decarta/decarta_directory.h @@ -0,0 +1,39 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef DECARTA_DIRECTORY_H_ +#define DECARTA_DIRECTORY_H_ + +#include +#include + +G_BEGIN_DECLS + +typedef void (*DecartaDirectoryCB)(DecartaError error, const gchar *req_id_str, const GList* poi_list, const gchar *error_code, const gchar *error_msg, void *userdata); + +int decarta_search_directory (const DecartaDirectoryRequest *dir_request, GList **poi_list); +int decarta_search_directory_async (const DecartaDirectoryRequest *directory_request, DecartaDirectoryCB callback, void *userdata); +void decarta_search_directory_async_cancel (guint request_id); + + +G_END_DECLS + +#endif diff --git a/decarta/decarta_geocode.c b/decarta/decarta_geocode.c new file mode 100644 index 0000000..a073b57 --- /dev/null +++ b/decarta/decarta_geocode.c @@ -0,0 +1,226 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "decarta_log.h" +#include "decarta_config.h" +#include "http_wrapper.h" +#include "decarta_xml.h" +#include "decarta_geocode.h" + +typedef struct { + DecartaGeocodeCB callback; + DecartaHandle *handle; + void* userdata; +} GeocodeCBData; + +typedef struct { + DecartaReverseGeocodeCB callback; + DecartaHandle *handle; + void* userdata; +} ReverseGeocodeCBData; + +struct _DecartaHandle { + HttpHandle http_async_geo; + HttpHandle http_async_rev_geo; +}; + +static void +search_reverse_geocode_cb (gboolean success, + char *recv_data, + void *userdata) +{ + DECARTA_LOGD("search_reverse_geocode_cb"); + ReverseGeocodeCBData* cb_data = (ReverseGeocodeCBData*)userdata; + DecartaError err = DECARTA_ERROR_NONE; + DecartaGeocode *geocode = NULL; + if (success != TRUE) err = DECARTA_ERROR_HTTP; + else if (!xml_reverse_geocode_parse(recv_data, &geocode)) err = DECARTA_ERROR_XML; + if (cb_data->callback) cb_data->callback (err, geocode, cb_data->userdata); + g_free(recv_data); + if (cb_data->handle) { + g_free(cb_data->handle); + cb_data->handle = NULL; + } + if (geocode) decarta_geocode_free (geocode); + g_free(cb_data); +} + +static void +search_geocode_cb (gboolean success, + char *recv_data, + void *userdata) +{ + DECARTA_LOGD("search_geocode_cb"); + GeocodeCBData* cb_data = (GeocodeCBData*)userdata; + DecartaError err = DECARTA_ERROR_NONE; + GList *geocode_ist = NULL; + if (success != TRUE) err = DECARTA_ERROR_HTTP; + else if (!xml_geocode_parse(recv_data, &geocode_ist)) err = DECARTA_ERROR_XML; + if (cb_data->callback) cb_data->callback (err, geocode_ist, cb_data->userdata); + g_free(recv_data); + if (cb_data->handle) { + g_free(cb_data->handle); + cb_data->handle = NULL; + } + if (geocode_ist) decarta_geocode_list_free (geocode_ist); + g_free(cb_data); +} + +EXPORT_API int +decarta_search_reverse_geocode (const DecartaPosition *pos, + DecartaGeocode **geocode) +{ + DECARTA_LOGD("decarta_search_reverse_geocode"); + if (!pos || !geocode) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + int err = DECARTA_ERROR_NONE; + char *req = NULL; + char *resp = NULL; + unsigned int size = 0; + if(!xml_reverse_geocode_request_get(pos, &req, &size)) return DECARTA_ERROR_PARAMETER; + HttpHandle http = http_open(HTTP_TYPE_SYNC); + if (http_send(http, req, get_host(), &resp, NULL, NULL)) { + if (!xml_reverse_geocode_parse(resp, geocode)) err = DECARTA_ERROR_XML; + } else err = DECARTA_ERROR_HTTP; + g_free (req); + g_free (resp); + http_close(http); + return err; +} + +EXPORT_API int +decarta_search_geocode (const DecartaAddress *address, + GList **geocode_list) +{ + DECARTA_LOGD("decarta_search_geocode"); + if (!address || !geocode_list) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + int err = DECARTA_ERROR_NONE; + char *req = NULL; + char *resp = NULL; + unsigned int size = 0; + if(!xml_geocode_request_get(address, &req, &size)) return DECARTA_ERROR_PARAMETER; + HttpHandle http = http_open(HTTP_TYPE_SYNC); + if (http_send(http, req, get_host(), &resp, NULL, NULL)) { + if (!xml_geocode_parse(resp, geocode_list)) err = DECARTA_ERROR_XML; + } else err = DECARTA_ERROR_HTTP; + g_free (req); + g_free (resp); + http_close(http); + return err; +} + +EXPORT_API int +decarta_search_reverse_geocode_async (const DecartaPosition *pos, + DecartaReverseGeocodeCB callback, + void *userdata, + DecartaHandle **handle) +{ + DECARTA_LOGD("decarta_search_reverse_geocode_async"); + if (!pos || !callback) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + *handle = NULL; + char* req = NULL; + unsigned int size = 0; + ReverseGeocodeCBData* cb_data = g_new0(ReverseGeocodeCBData, 1); + cb_data->callback = callback; + cb_data->userdata = userdata; + if(!xml_reverse_geocode_request_get(pos, &req, &size)) { + g_free(cb_data); + return DECARTA_ERROR_PARAMETER; + } + *handle = g_new0(DecartaHandle, 1); + (*handle)->http_async_rev_geo = http_open(HTTP_TYPE_ASYNC); + cb_data->handle = *handle; + if(!http_send((*handle)->http_async_rev_geo, req, get_host(), NULL, (HttpCallback)search_reverse_geocode_cb, cb_data)){ + http_close((*handle)->http_async_rev_geo); + g_free(*handle); + *handle = NULL; + return DECARTA_ERROR_HTTP; + } + g_free(req); + + return DECARTA_ERROR_NONE; +} + +EXPORT_API int +decarta_search_geocode_async (const DecartaAddress *addr, + DecartaGeocodeCB callback, + void *userdata, + DecartaHandle **handle) +{ + DECARTA_LOGD("decarta_search_geocode_async"); + if (!addr || !callback) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + *handle = NULL; + char* req = NULL; + unsigned int size = 0; + GeocodeCBData* cb_data = g_new0(GeocodeCBData, 1); + cb_data->callback = callback; + cb_data->userdata = userdata; + if(!xml_geocode_request_get(addr, &req, &size)) { + g_free(cb_data); + return DECARTA_ERROR_PARAMETER; + } + *handle = g_new0(DecartaHandle, 1); + (*handle)->http_async_geo = http_open(HTTP_TYPE_ASYNC); + cb_data->handle = *handle; + if(!http_send((*handle)->http_async_geo, req, get_host(), NULL, (HttpCallback)search_geocode_cb, cb_data)){ + http_close((*handle)->http_async_geo); + g_free(*handle); + *handle = NULL; + return DECARTA_ERROR_HTTP; + } + g_free(req); + + return DECARTA_ERROR_NONE; +} + +EXPORT_API void +decarta_search_geocode_async_cancel (DecartaHandle *handle) +{ + DECARTA_LOGD("decarta_search_geocode_async_cancel"); + if (handle == NULL) return; + if (handle->http_async_geo) { + http_close (handle->http_async_geo); + handle->http_async_geo = NULL; + } +} + +EXPORT_API void +decarta_search_reverse_geocode_async_cancel (DecartaHandle *handle) +{ + DECARTA_LOGD("decarta_search_reverse_geocode_async_cancel"); + if (handle == NULL) return; + if (handle->http_async_rev_geo) { + http_close (handle->http_async_rev_geo); + handle->http_async_rev_geo = NULL; + } +} diff --git a/decarta/decarta_geocode.h b/decarta/decarta_geocode.h new file mode 100644 index 0000000..8fb490b --- /dev/null +++ b/decarta/decarta_geocode.h @@ -0,0 +1,46 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_GEOCODE_H_ +#define _DECARTA_GEOCODE_H_ + +#include +#include + +G_BEGIN_DECLS + +typedef void (*DecartaGeocodeCB) (DecartaError error, const GList *geocode_list, void *userdata); +typedef void (*DecartaReverseGeocodeCB) (DecartaError error, const DecartaGeocode *geocode, void *userdata); + +int decarta_search_geocode (const DecartaAddress *address, GList **geocode_list); +int decarta_search_reverse_geocode (const DecartaPosition *pos, DecartaGeocode **geocode); + +typedef struct _DecartaHandle DecartaHandle; + +int decarta_search_geocode_async (const DecartaAddress *addr, DecartaGeocodeCB callback, void *userdata, DecartaHandle **handle); +int decarta_search_reverse_geocode_async (const DecartaPosition *pos, DecartaReverseGeocodeCB callback, void *userdata, DecartaHandle **handle); + +void decarta_search_geocode_async_cancel (DecartaHandle *handle); +void decarta_search_reverse_geocode_async_cancel (DecartaHandle *handle); + +G_END_DECLS + +#endif diff --git a/decarta/decarta_log.h b/decarta/decarta_log.h new file mode 100644 index 0000000..dcb8f03 --- /dev/null +++ b/decarta/decarta_log.h @@ -0,0 +1,46 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_LOG_H_ +#define _DECARTA_LOG_H_ + +#define TAG_DECARTA "decarta" + +#ifdef DECARTA_DLOG_DEBUG // if debug mode, show filename & line number +#include +#define DECARTA_LOGD(fmt,args...) SLOG(LOG_DEBUG, TAG_DECARTA, "[%-15s:%-4d:%-27s]"fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args) +#define DECARTA_LOGW(fmt,args...) SLOG(LOG_WARN, TAG_DECARTA, "[%-15s:%-4d:%-27s]"fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args) +#define DECARTA_LOGI(fmt,args...) SLOG(LOG_INFO, TAG_DECARTA, "[%-15s:%-4d:%-27s]"fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args) +#define DECARTA_LOGE(fmt,args...) SLOG(LOG_ERROR, TAG_DECARTA, "[%-15s:%-4d:%-27s]"fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args) +#elif DECARTA_DLOG_RELEASE // if release mode, do not show filename & line number +#include +#define DECARTA_LOGD(fmt,args...) SLOG(LOG_DEBUG, TAG_DECARTA, fmt, ##args) +#define DECARTA_LOGW(fmt,args...) SLOG(LOG_WARN, TAG_DECARTA, fmt, ##args) +#define DECARTA_LOGI(fmt,args...) SLOG(LOG_INFO, TAG_DECARTA, fmt, ##args) +#define DECARTA_LOGE(fmt,args...) SLOG(LOG_ERROR, TAG_DECARTA, fmt, ##args) +#else // if do not use dlog +#define DECARTA_LOGD(...) g_debug(__VA_ARGS__); +#define DECARTA_LOGW(...) g_warning(__VA_ARGS__); +#define DECARTA_LOGI(...) g_message(__VA_ARGS__); +#define DECARTA_LOGE(...) g_error(__VA_ARGS__); +#endif + +#endif diff --git a/decarta/decarta_maps.c b/decarta/decarta_maps.c new file mode 100755 index 0000000..abcc14a --- /dev/null +++ b/decarta/decarta_maps.c @@ -0,0 +1,243 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "decarta_log.h" +#include "decarta_config.h" +#include "http_wrapper.h" +#include "decarta_xml.h" +#include "decarta_maps.h" + +typedef struct { + DecartaMapCB callback; + void *userdata; + guint request_id; /**< used to remove from table after success */ +} DecartaMapCBData; + +static GHashTable *http_reqid_hash = NULL; +static guint request_id = 1; + +static gboolean +__maps_del_table_node_cb(gpointer key, + gpointer value, + gpointer user_data) +{ + if (!user_data || !key || !value) { + return false; + } + HttpHandle http_async = NULL; + + http_async = (HttpHandle)value; + char *user_key = (char *)user_data; + char *table_key = (char *)key; + + if (!g_strcmp0(user_key, table_key)) { + DECARTA_LOGD("req_id [%s] http_async [%d] closed!", table_key, http_async); + g_free(table_key); + http_close(http_async); + return true; + } + DECARTA_LOGD("req_id [%s] http_async [%d] not close", table_key, http_async); + return false; +} + +static gboolean +__maps_del_table_all_cb(gpointer key, + gpointer value, + gpointer user_data) +{ + if (!key || !value) { + return false; + } + + HttpHandle http_async = NULL; + http_async = (HttpHandle)value; + char *table_key = (char *)key; + + DECARTA_LOGD("req_id [%s] http_async [%d] closed!", table_key, http_async); + g_free(table_key); + http_close(http_async); + return true; +} + +static void +http_map_cb (gboolean success, + char *recv_data, + void *userdata) +{ + DECARTA_LOGD("map_cb"); + DecartaMapCBData* cb_data = (DecartaMapCBData*)userdata; + DecartaError err = DECARTA_ERROR_NONE; + DecartaMap *map = NULL; + if (success != TRUE) err = DECARTA_ERROR_HTTP; + else if (!xml_map_parse (recv_data, &map)) err = DECARTA_ERROR_XML; + if (cb_data->callback) cb_data->callback (err, map, cb_data->userdata); + + /** remove the success request id from hash table */ + char *request_id_str = g_strdup_printf("%u", cb_data->request_id); + if (http_reqid_hash) { + DECARTA_LOGD("remove the http async after success!"); + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__maps_del_table_node_cb, (gpointer)request_id_str); + if (!g_hash_table_size(http_reqid_hash)) { + g_hash_table_destroy(http_reqid_hash); + http_reqid_hash = NULL; + } + } + if (request_id_str) { + g_free(request_id_str); + } + + g_free(recv_data); + if (map) decarta_map_free (map); + g_free(cb_data); +} + +EXPORT_API int +decarta_search_map (const DecartaPosition *pos, + int zoom, + DecartaMap **map) +{ + DECARTA_LOGD("decarta_search_geocode"); + if (!pos || !map) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + int err = DECARTA_ERROR_NONE; + char *req = NULL; + char *resp = NULL; + unsigned int size = 0; + if (!xml_map_request_get(pos, zoom, &req, &size)) return DECARTA_ERROR_PARAMETER; + HttpHandle http = http_open(HTTP_TYPE_SYNC); + if (http_send(http, req, get_host(), &resp, NULL, NULL)) { + + if (!xml_map_parse (resp, map)) err = DECARTA_ERROR_XML; + //if( 0 != process_tile_grid(resp, map)) err = DECARTA_ERROR_XML; + + } else err = DECARTA_ERROR_HTTP; + g_free (req); + g_free (resp); + http_close(http); + return err; +} + +EXPORT_API int +decarta_search_map_async (const DecartaPosition *pos, + int zoom, + DecartaMapCB callback, + void *userdata) +{ + DECARTA_LOGD("decarta_search_map_async"); + if (!pos || !callback) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + char* req = NULL; + unsigned int size = 0; + DecartaMapCBData* cb_data = g_new0(DecartaMapCBData, 1); + cb_data->callback = callback; + cb_data->userdata = userdata; + request_id++; + cb_data->request_id = request_id; + + if (!xml_map_request_get(pos, zoom, &req, &size)) { + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_PARAMETER; + } + + char *request_id_str = g_strdup_printf("%u", request_id); + if (request_id_str == NULL) { + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_PARAMETER; + } + + HttpHandle http_async = http_open(HTTP_TYPE_ASYNC); + + if (!http_reqid_hash) { + http_reqid_hash = g_hash_table_new(g_str_hash, g_str_equal); + if (http_reqid_hash == NULL) { + if (request_id_str) { + g_free(request_id_str); + } + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + http_close(http_async); + return DECARTA_ERROR_HTTP; + } + g_hash_table_insert(http_reqid_hash, (gpointer)request_id_str, (gpointer)http_async); + DECARTA_LOGD("first insert http [0x%x], req_id [%d]", http_async, request_id); + } else { + g_hash_table_insert(http_reqid_hash, (gpointer)request_id_str, (gpointer)http_async); + DECARTA_LOGD("Not the first insert http [0x%x], req_id [%d]", http_async, request_id); + } + + if(!http_send(http_async, req, get_host(), NULL, (HttpCallback)http_map_cb, cb_data)){ + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__maps_del_table_node_cb, (gpointer)request_id_str); + if (!g_hash_table_size(http_reqid_hash)) { + g_hash_table_destroy(http_reqid_hash); + http_reqid_hash = NULL; + } + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_HTTP; + } + + if (req) { + g_free(req); + } + + return DECARTA_ERROR_NONE; +} + +EXPORT_API void +decarta_search_map_async_cancel (void) +{ + if (http_reqid_hash) { + /** cancel the all rest mapping http async requests*/ + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__maps_del_table_all_cb, NULL); + } else { + DECARTA_LOGD("decarta_search_map_async_cancel: http_reqid_hash NOT exist!"); + } +} diff --git a/decarta/decarta_maps.h b/decarta/decarta_maps.h new file mode 100644 index 0000000..8a06315 --- /dev/null +++ b/decarta/decarta_maps.h @@ -0,0 +1,37 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_MAPS_H_ +#define _DECARTA_MAPS_H_ + +#include + +G_BEGIN_DECLS + +typedef void (*DecartaMapCB)(DecartaError error, const DecartaMap *map, void *userdata); + +int decarta_search_map (const DecartaPosition *pos, int zoom, DecartaMap **map); +int decarta_search_map_async (const DecartaPosition *pos, int zoom, DecartaMapCB callback, void *userdata); +void decarta_search_map_async_cancel (void); + +G_END_DECLS + +#endif \ No newline at end of file diff --git a/decarta/decarta_route.c b/decarta/decarta_route.c new file mode 100755 index 0000000..5b1a754 --- /dev/null +++ b/decarta/decarta_route.c @@ -0,0 +1,271 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "decarta_log.h" +#include "decarta_config.h" +#include "http_wrapper.h" +#include "decarta_xml.h" +#include "decarta_route.h" + +typedef struct { + DecartaRouteCB callback; + void *userdata; + guint request_id; /**< used to remove from table after success */ +} DecartaRouteCBData; + +static GHashTable *http_reqid_hash = NULL; +static bool is_found = false; + +static gboolean +__route_del_table_node_cb(gpointer key, + gpointer value, + gpointer user_data) +{ + if (!user_data || !key || !value) { + return false; + } + HttpHandle http_async = NULL; + + http_async = (HttpHandle)value; + char *user_key = (char *)user_data; + char *table_key = (char *)key; + + if (!g_strcmp0(user_key, table_key)) { + DECARTA_LOGD("req_id [%s] http_async [%d] closed!", table_key, http_async); + g_free(table_key); + http_close(http_async); + is_found = true; + return true; + } + DECARTA_LOGD("req_id [%s] http_async [%d] not close", table_key, http_async); + return false; +} + +static void +search_route_cb (gboolean success, + char *recv_data, + void *user_data) +{ + DECARTA_LOGD("search_route_cb"); + DecartaRouteCBData* cb_data = (DecartaRouteCBData*)user_data; + DecartaError err = DECARTA_ERROR_NONE; + DecartaRoute *route = NULL; + gchar *req_id_str = NULL; + gchar *error_code = NULL; + gchar *error_msg = NULL; + if (success != TRUE) err = DECARTA_ERROR_HTTP; + else if (!xml_route_parse(recv_data, &route, &req_id_str, &error_code, &error_msg)) err = DECARTA_ERROR_XML; + + if (cb_data && cb_data->callback) cb_data->callback (err, req_id_str, route, error_code, error_msg, cb_data->userdata); + DECARTA_LOGD("search_route_cb callback called"); + + /** remove the success request id from hash table */ + char *request_id_str = g_strdup_printf("%u", cb_data->request_id); + if (http_reqid_hash) { + DECARTA_LOGD("remove the http async after success!"); + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__route_del_table_node_cb, (gpointer)request_id_str); + if (!g_hash_table_size(http_reqid_hash)) { + g_hash_table_destroy(http_reqid_hash); + http_reqid_hash = NULL; + } + } + if (request_id_str) { + g_free(request_id_str); + } + + if (recv_data) { + g_free(recv_data); + } + if (route) { + decarta_route_free (route); + } + if (req_id_str) { + g_free(req_id_str); + } + if (error_code) { + g_free(error_code); + } + if (error_msg) { + g_free(error_msg); + } + if (cb_data) { + g_free(cb_data); + } +} + +EXPORT_API int +decarta_search_route (const DecartaRouteRequest *request, + DecartaRoute **route) +{ + DECARTA_LOGD("decarta_search_route"); + if (!request || !route) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + int err = DECARTA_ERROR_NONE; + char *req = NULL; + char *resp = NULL; + unsigned int size = 0; + gchar *req_id_str = NULL; + gchar *error_code = NULL; + gchar *error_msg = NULL; + if (!xml_route_request_get(request, &req, &size)) return DECARTA_ERROR_PARAMETER; + HttpHandle http = http_open(HTTP_TYPE_SYNC); + if (http_send(http, req, get_host(), &resp, NULL, NULL)) { + if (!xml_route_parse(resp, route, &req_id_str, &error_code, &error_msg)) err = DECARTA_ERROR_XML; + } else err = DECARTA_ERROR_HTTP; + if (req) { + g_free (req); + } + if (resp) { + g_free (resp); + } + if (req_id_str) { + g_free(req_id_str); + } + if (error_code) { + g_free(error_code); + } + if (error_msg) { + g_free(error_msg); + } + http_close(http); + return err; +} + +EXPORT_API int +decarta_search_route_async (const DecartaRouteRequest *request, + DecartaRouteCB callback, + void *userdata) +{ + DECARTA_LOGD("decarta_search_route_async"); + if (!request || !callback) return DECARTA_ERROR_PARAMETER; + if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE; + + char* req = NULL; + unsigned int size = 0; + DecartaRouteCBData* cb_data = g_new0(DecartaRouteCBData, 1); + cb_data->callback = callback; + cb_data->userdata = userdata; + cb_data->request_id = request->request_id; + + if (!xml_route_request_get(request, &req, &size)) { + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_PARAMETER; + } + + char *request_id_str = g_strdup_printf("%u", request->request_id); + if (request_id_str == NULL) { + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_PARAMETER; + } + + HttpHandle http_async = http_open(HTTP_TYPE_ASYNC); + DECARTA_LOGD("decarta_search_route_async: http %d, req_id %d", http_async, request->request_id); + + if (!http_reqid_hash) { + http_reqid_hash = g_hash_table_new(g_str_hash, g_str_equal); + if (http_reqid_hash == NULL) { + if (request_id_str) { + g_free(request_id_str); + } + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + http_close(http_async); + return DECARTA_ERROR_HTTP; + } + g_hash_table_insert(http_reqid_hash, (gpointer)request_id_str, (gpointer)http_async); + DECARTA_LOGD("first insert http [0x%x], req_id [%d]", http_async, request->request_id); + } else { + g_hash_table_insert(http_reqid_hash, (gpointer)request_id_str, (gpointer)http_async); + DECARTA_LOGD("Not the first insert http [0x%x], req_id [%d]", http_async, request->request_id); + } + + if(!http_send(http_async, req, get_host(), NULL, (HttpCallback)search_route_cb, cb_data)){ + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__route_del_table_node_cb, (gpointer)request_id_str); + if (!g_hash_table_size(http_reqid_hash)) { + g_hash_table_destroy(http_reqid_hash); + http_reqid_hash = NULL; + } + + if (cb_data) { + g_free(cb_data); + cb_data = NULL; + } + if (req) { + g_free(req); + } + return DECARTA_ERROR_HTTP; + } + + // cb_data will be freed in callback + if (req) { + g_free(req); + } + return DECARTA_ERROR_NONE; +} + +EXPORT_API int +decarta_search_route_async_cancel (guint request_id) +{ + DECARTA_LOGD("decarta_search_route_async_cancel: req_id %d called", request_id); + + if (http_reqid_hash) { + char *request_id_str = g_strdup_printf("%u", request_id); + if (request_id_str == NULL) { + return DECARTA_ERROR_NOT_FOUND; + } + + /** cancel the request_id http async request*/ + is_found = false; + g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__route_del_table_node_cb, (gpointer)request_id_str); + g_free(request_id_str); + if (is_found == false) { + return DECARTA_ERROR_NOT_FOUND; + } + } else { + DECARTA_LOGD("decarta_search_route_async_cancel: req_id %d http_reqid_hash NOT exist!", request_id); + return DECARTA_ERROR_NOT_FOUND; + } + + return DECARTA_ERROR_NONE; +} diff --git a/decarta/decarta_route.h b/decarta/decarta_route.h new file mode 100755 index 0000000..56b7a1c --- /dev/null +++ b/decarta/decarta_route.h @@ -0,0 +1,38 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_ROUTE_H_ +#define _DECARTA_ROUTE_H_ + +#include + +G_BEGIN_DECLS + +typedef void (*DecartaRouteCB)(DecartaError error, const gchar *req_id_str, const DecartaRoute *route, const gchar * error_code, const gchar * error_msg, void *user_data); + + +int decarta_search_route (const DecartaRouteRequest *request, DecartaRoute **route); +int decarta_search_route_async (const DecartaRouteRequest *request, DecartaRouteCB callback, void *userdata); +int decarta_search_route_async_cancel (guint request_id); + +G_END_DECLS + +#endif diff --git a/decarta/decarta_types.c b/decarta/decarta_types.c new file mode 100755 index 0000000..c358c94 --- /dev/null +++ b/decarta/decarta_types.c @@ -0,0 +1,947 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +EXPORT_API DecartaPosition * +decarta_position_new (double latitude, + double longitude) +{ + DecartaPosition *pos = g_new0 (DecartaPosition, 1); + pos->latitude = latitude; + pos->longitude = longitude; + return pos; +} + +EXPORT_API DecartaPosition * +decarta_position_copy (const DecartaPosition *pos) +{ + g_return_val_if_fail (pos, NULL); + return decarta_position_new (pos->latitude, pos->longitude); +} + +EXPORT_API void +decarta_position_free (DecartaPosition *pos) +{ + g_return_if_fail (pos); + g_free (pos); +} + +static void +_position_list_free_gfunc (gpointer data, + gpointer user_data) +{ + DecartaPosition* pos = (DecartaPosition*)data; + decarta_position_free (pos); +} + +EXPORT_API GList* +decarta_position_list_append (GList *pos_list, DecartaPosition *pos) +{ + g_return_val_if_fail (pos, NULL); + return g_list_append (pos_list, (gpointer)pos); +} + +EXPORT_API void +decarta_position_list_free (GList *pos_list) +{ + g_return_if_fail (pos_list); + g_list_foreach(pos_list, (GFunc)_position_list_free_gfunc, NULL); + g_list_free (pos_list); +} + +EXPORT_API GList * +decarta_position_list_next (const GList *pos_list, + const DecartaPosition ** pos) +{ + g_return_val_if_fail (pos_list, NULL); + g_return_val_if_fail (pos, NULL); + *pos = (DecartaPosition*)pos_list->data; + return g_list_next (pos_list); +} + +EXPORT_API GList * +decarta_position_list_copy (const GList *pos_list) +{ + g_return_val_if_fail (pos_list, NULL); + GList *dup_pos_list = NULL; + const DecartaPosition *pos = NULL; + pos_list = decarta_position_list_next(pos_list, &pos); + while (pos) { + dup_pos_list = decarta_position_list_append (dup_pos_list, decarta_position_copy (pos)); + if (!pos_list) break; + pos_list = decarta_position_list_next(pos_list, &pos); + } + return dup_pos_list; +} + +EXPORT_API DecartaFormedAddress * +decarta_formed_address_new (const char *street_number, + const char *street_name, + const char *state, + const char *county, + const char *city, + const char *district, + const char* postal_code, + const char* landmark_type, + const char* landmark_name) +{ + DecartaFormedAddress *formed_addr = g_new0 (DecartaFormedAddress, 1 ); + formed_addr->street_number = g_strdup (street_number); + formed_addr->street_name = g_strdup (street_name); + formed_addr->state = g_strdup (state); + formed_addr->county = g_strdup (county); + formed_addr->city = g_strdup (city); + formed_addr->district = g_strdup (district); + formed_addr->postal_code = g_strdup (postal_code); + formed_addr->landmark_type = g_strdup (landmark_type); + formed_addr->landmark_name = g_strdup (landmark_name); + return formed_addr; +} + +EXPORT_API void +decarta_formed_address_free (DecartaFormedAddress *formed_addr) +{ + g_return_if_fail (formed_addr); + g_free(formed_addr->street_number); + g_free(formed_addr->street_name); + g_free(formed_addr->state); + g_free(formed_addr->county); + g_free(formed_addr->city ); + g_free(formed_addr->district); + g_free(formed_addr->postal_code); + g_free(formed_addr->landmark_type); + g_free(formed_addr->landmark_name); + g_free(formed_addr); +} + +EXPORT_API DecartaFormedAddress * +decarta_formed_address_copy (const DecartaFormedAddress *formed_addr) +{ + g_return_val_if_fail (formed_addr, NULL); + return decarta_formed_address_new (formed_addr->street_number, formed_addr->street_name, formed_addr->state, formed_addr->county, formed_addr->city, formed_addr->district, formed_addr->postal_code, formed_addr->landmark_type, formed_addr->landmark_name); +} + +EXPORT_API DecartaAddress * +decarta_address_new (const char* country_code, + const char *language_code, + gboolean is_freerorm, + const char *freeform_address, + const DecartaFormedAddress *formed_addr) +{ + DecartaAddress *addr = g_new0 (DecartaAddress, 1 ); + addr->country_code = g_strdup (country_code); + addr->language_code = g_strdup (language_code); + addr->is_freerorm = is_freerorm; + if (addr->is_freerorm) addr->freeform_address = g_strdup (freeform_address); + else addr->formed_addr = decarta_formed_address_copy (formed_addr); + return addr; +} + +EXPORT_API void +decarta_address_free (DecartaAddress *addr) +{ + g_return_if_fail (addr); + g_free(addr->country_code); + g_free(addr->language_code); + if (addr->is_freerorm) g_free (addr->freeform_address); + else decarta_formed_address_free (addr->formed_addr); + g_free (addr); +} + +EXPORT_API DecartaBoundary * +decarta_boundary_new_for_rect (DecartaPosition* left_top, + DecartaPosition* right_bottom) +{ + g_return_val_if_fail(left_top, NULL); + g_return_val_if_fail(right_bottom, NULL); + + gdouble lon_interval = right_bottom->longitude - left_top->longitude; + + if(lon_interval < 180 && lon_interval > -180) { + if(right_bottom->longitude <= left_top->longitude || right_bottom->latitude >= left_top->latitude) + return NULL; + } + else { + if(right_bottom->longitude >= left_top->longitude || right_bottom->latitude >= left_top->latitude) + return NULL; + } + + DecartaBoundary* boundary = g_slice_new0 (DecartaBoundary); + boundary->type = DECARTA_BOUNDARY_RECT; + boundary->rect.left_top = decarta_position_copy(left_top); + boundary->rect.right_bottom = decarta_position_copy(right_bottom); + return boundary; +} + +EXPORT_API DecartaBoundary * +decarta_boundary_new_for_circle (DecartaPosition* center, + gdouble radius) +{ + g_return_val_if_fail(center, NULL); + g_return_val_if_fail(radius > 0, NULL); + DecartaBoundary* boundary = g_slice_new0 (DecartaBoundary); + boundary->type = DECARTA_BOUNDARY_CIRCLE; + boundary->circle.center = decarta_position_copy(center); + boundary->circle.radius = radius; + return boundary; +} + +static void __decarta_append_polygon_position(gpointer data, gpointer user_data) +{ + g_return_if_fail(data); + g_return_if_fail(user_data); + + DecartaBoundary* boundary = (DecartaBoundary*)user_data; + DecartaPosition* position = (DecartaPosition *)data; + DecartaPosition* new_position = decarta_position_copy(position); + + boundary->polygon.position_list = g_list_append(boundary->polygon.position_list, new_position); +} + + +EXPORT_API DecartaBoundary * +decarta_boundary_new_for_polygon(GList *position_list) +{ + g_return_val_if_fail(position_list, NULL); + g_return_val_if_fail(g_list_length(position_list) > 2, NULL); + + DecartaBoundary *boundary = g_slice_new0 (DecartaBoundary); + + g_list_foreach(position_list, (GFunc)__decarta_append_polygon_position, boundary); + boundary->type = DECARTA_BOUNDARY_POLYGON; + boundary->polygon.position_list = g_list_first(boundary->polygon.position_list); + + return boundary; +} + +static void __decarta_free_polygon_position(gpointer data) +{ + g_return_if_fail(data); + + DecartaPosition* position = (DecartaPosition *)data; + decarta_position_free(position); +} + +EXPORT_API void +decarta_boundary_free (DecartaBoundary* boundary) +{ + g_return_if_fail(boundary); + + if (boundary->type == DECARTA_BOUNDARY_RECT) { + decarta_position_free(boundary->rect.left_top); + decarta_position_free(boundary->rect.right_bottom); + } else if (boundary->type == DECARTA_BOUNDARY_CIRCLE) { + decarta_position_free(boundary->circle.center); + } else if (boundary->type == DECARTA_BOUNDARY_POLYGON) { + g_list_free_full(boundary->polygon.position_list, (GDestroyNotify)__decarta_free_polygon_position); + } + g_slice_free(DecartaBoundary, boundary); +} + +EXPORT_API DecartaBoundary* +decarta_boundary_copy (const DecartaBoundary* boundary) +{ + g_return_val_if_fail(boundary, NULL); + if (boundary->type == DECARTA_BOUNDARY_RECT) { + return decarta_boundary_new_for_rect(boundary->rect.left_top, boundary->rect.right_bottom); + } else if (boundary->type == DECARTA_BOUNDARY_CIRCLE) { + return decarta_boundary_new_for_circle(boundary->circle.center, boundary->circle.radius); + } else if (boundary->type == DECARTA_BOUNDARY_POLYGON) { + return decarta_boundary_new_for_polygon(boundary->polygon.position_list); + } + return NULL; +} + +EXPORT_API gboolean +decarta_boundary_if_inside (DecartaBoundary* boundary, + const DecartaPosition* position) +{ + g_return_val_if_fail(boundary, FALSE); + g_return_val_if_fail(position, FALSE); + + gboolean is_inside = FALSE; + + switch(boundary->type) { + + case DECARTA_BOUNDARY_RECT: { + gdouble y = position->latitude; + gdouble x = position->longitude; + + gdouble lt_y = boundary->rect.left_top->latitude; + gdouble lt_x = boundary->rect.left_top->longitude; + gdouble rb_y = boundary->rect.right_bottom->latitude; + gdouble rb_x = boundary->rect.right_bottom->longitude; + + if (lt_x - rb_x < 180 && lt_x - rb_x > -180) { + if ((rb_y < y && y < lt_y) && ( lt_x < x && x < rb_x)) { + is_inside = TRUE; + } + } + else { + if ((rb_y < y && y < lt_y) && ( lt_x < x || x < rb_x)) { + is_inside = TRUE; + } + } + break; + } + case DECARTA_BOUNDARY_CIRCLE: { + break; + } + case DECARTA_BOUNDARY_POLYGON: { + break; + } + default: { + break; + } + } + + return is_inside; +} + + +EXPORT_API DecartaAddress * +decarta_addr_copy (const DecartaAddress *addr) +{ + g_return_val_if_fail(addr, NULL); + return decarta_address_new (addr->country_code, addr->language_code, addr->is_freerorm, addr->freeform_address, addr->formed_addr); +} + +EXPORT_API DecartaPOI * +decarta_poi_new (const char *name, + const char* id, + const char* phone_number, + const DecartaPOIInfoTable* info_list, + const DecartaPosition *pos, + const DecartaAddress *addr, + double distance) +{ + DecartaPOI *poi = g_new0 (DecartaPOI, 1 ); + poi->name = g_strdup (name); + poi->id = g_strdup (id); + poi->phone_number = g_strdup (phone_number); + poi->info_list = decarta_poi_info_table_copy (info_list); + poi->pos = decarta_position_copy (pos); + poi->addr = decarta_addr_copy (addr); + poi->distance = distance; + return poi; +} + +EXPORT_API void +decarta_poi_free (DecartaPOI *poi) +{ + g_return_if_fail (poi); + g_free (poi->name); + g_free (poi->id); + g_free (poi->phone_number); + decarta_poi_info_table_free (poi->info_list); + decarta_address_free (poi->addr); + g_free (poi); +} + +EXPORT_API DecartaPOI * +decarta_poi_copy (const DecartaPOI *poi) +{ + g_return_val_if_fail(poi, NULL); + return decarta_poi_new (poi->name, poi->id, poi->phone_number, poi->info_list, poi->pos, poi->addr, poi->distance); +} + +static void +_poi_list_free_gfunc (gpointer data, + gpointer user_data) +{ + DecartaPOI* poi = (DecartaPOI*)data; + decarta_poi_free (poi); +} + +EXPORT_API GList* +decarta_poi_list_append (GList *poi_list, DecartaPOI *poi) +{ + g_return_val_if_fail (poi, NULL); + return g_list_append (poi_list, (gpointer)poi); +} + +EXPORT_API void decarta_poi_list_free (GList *poi_list) +{ + g_return_if_fail (poi_list); + g_list_foreach(poi_list, (GFunc)_poi_list_free_gfunc, NULL); + g_list_free (poi_list); +} + +EXPORT_API GList * +decarta_poi_list_next (const GList *poi_list, + const DecartaPOI** poi) +{ + g_return_val_if_fail (poi_list, NULL); + g_return_val_if_fail (poi, NULL); + *poi = (DecartaPOI*)poi_list->data; + return g_list_next (poi_list); +} + +EXPORT_API GList * +decarta_poi_list_copy (const GList *poi_list) +{ + g_return_val_if_fail (poi_list, NULL); + GList *dup_poi_list = NULL; + const DecartaPOI *poi = NULL; + poi_list = decarta_poi_list_next(poi_list, &poi); + while (poi) { + dup_poi_list = g_list_append (dup_poi_list, decarta_poi_copy (poi)); + if (!poi_list) break; + poi_list = decarta_poi_list_next(poi_list, &poi); + } + return dup_poi_list; +} + +EXPORT_API DecartaPOIInfoTable * +decarta_poi_info_table_new (void) +{ + DecartaPOIInfoTable *info_list = g_new0 (DecartaPOIInfoTable, 1); + info_list->table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + return info_list; +} + +EXPORT_API void +decarta_poi_info_table_free (DecartaPOIInfoTable* poi_info_list) +{ + g_return_if_fail(poi_info_list); + g_return_if_fail(poi_info_list->table); + g_hash_table_destroy(poi_info_list->table); + g_free (poi_info_list); +} + +EXPORT_API gboolean +decarta_poi_info_table_insert (DecartaPOIInfoTable* poi_info_list, + const gchar* name, + const gchar* value) +{ + g_return_val_if_fail(poi_info_list, FALSE); + g_return_val_if_fail(poi_info_list->table, FALSE); + g_hash_table_insert (poi_info_list->table, g_strdup(name), g_strdup(value)); + return TRUE; +} + +EXPORT_API gboolean +decarta_poi_info_table_iter_init (DecartaPOIInfoTable* poi_info_list) +{ + g_return_val_if_fail(poi_info_list, FALSE); + g_return_val_if_fail(poi_info_list->table, FALSE); + g_hash_table_iter_init (&poi_info_list->iter, poi_info_list->table); + return TRUE; +} + +EXPORT_API gboolean +decarta_poi_info_list_table_next (DecartaPOIInfoTable* poi_info_list, + gchar** name, + gchar** value) +{ + g_return_val_if_fail(poi_info_list, FALSE); + g_return_val_if_fail(poi_info_list->table, FALSE); + return g_hash_table_iter_next (&poi_info_list->iter, (gpointer*)name, (gpointer*)value); +} + +static void +copy_poi_info_table_func (gchar *key, + gchar *value, + DecartaPOIInfoTable *dup) +{ + g_return_if_fail (dup); + decarta_poi_info_table_insert(dup, key, value); +} + +EXPORT_API DecartaPOIInfoTable * +decarta_poi_info_table_copy (const DecartaPOIInfoTable *poi_info_list) +{ + g_return_val_if_fail(poi_info_list, NULL); + DecartaPOIInfoTable *dup = decarta_poi_info_table_new (); + g_hash_table_foreach (poi_info_list->table, + (GHFunc)copy_poi_info_table_func, + dup); + return dup; +} + +EXPORT_API DecartaPOIProperty * +decarta_poi_property_new (const char* poi_name, + const char* keyword, + const char* brand, + const char* type, + const char* description, + const char* URL) +{ + DecartaPOIProperty *property = g_new0 (DecartaPOIProperty, 1 ); + property->poi_name = g_strdup(poi_name); + property->keyword = g_strdup(keyword); + property->brand = g_strdup(brand); + property->type = g_strdup(type); + property->description = g_strdup(description); + property->URL = g_strdup(URL); + return property; +} + +EXPORT_API void +decarta_poi_property_free (DecartaPOIProperty *property) +{ + g_return_if_fail (property); + g_free (property->poi_name); + g_free (property->keyword); + g_free (property->brand); + g_free (property->type); + g_free (property->description); + g_free (property->URL); + g_free (property); +} + +EXPORT_API DecartaPOIProperty * +decarta_poi_property_copy (const DecartaPOIProperty *property) +{ + g_return_val_if_fail(property, NULL); + return decarta_poi_property_new (property->poi_name, property->keyword, property->brand, property->type, property->description, property->URL); +} + + +EXPORT_API DecartaPOIPreference * +decarta_poi_preference_new (guint max_result_cnt, + DecartaPOIPrefSortOrder sort_order, + const gchar *item) +{ + DecartaPOIPreference *pref = g_new0 (DecartaPOIPreference, 1 ); + pref->max_result_cnt = max_result_cnt; + pref->sort_order = sort_order; + pref->item = g_strdup(item); + return pref; +} + +EXPORT_API void +decarta_poi_preference_free (DecartaPOIPreference *preference) +{ + g_return_if_fail (preference); + g_free (preference->item); + g_free (preference); +} + +EXPORT_API DecartaPOIPreference * +decarta_poi_preference_copy (const DecartaPOIPreference *preference) +{ + g_return_val_if_fail(preference, NULL); + //When decarta_directory_request_new() was call without item, it reaturns fail. + //g_return_val_if_fail(preference->item, NULL); + return decarta_poi_preference_new(preference->max_result_cnt, preference->sort_order, preference->item); +} + +EXPORT_API DecartaGeocode * +decarta_geocode_new (const DecartaPosition *pos, + const DecartaAddress *addr) +{ + DecartaGeocode *geocode = g_new0 (DecartaGeocode, 1); + if (pos) geocode->pos = decarta_position_copy (pos); + if (addr) geocode->addr = decarta_addr_copy (addr); + return geocode; +} + +EXPORT_API DecartaGeocode * +decarta_geocode_copy (const DecartaGeocode *geocode) +{ + g_return_val_if_fail (geocode, NULL); + return decarta_geocode_new (geocode->pos, geocode->addr); +} + +EXPORT_API void +decarta_geocode_free (DecartaGeocode *geocode) +{ + g_return_if_fail (geocode); + if (geocode->pos) decarta_position_free (geocode->pos); + if (geocode->addr) decarta_address_free (geocode->addr); + g_free (geocode); +} + +static void +_geocode_list_free_gfunc (gpointer data, + gpointer user_data) +{ + DecartaGeocode* geocode = (DecartaGeocode*)data; + decarta_geocode_free (geocode); +} + +EXPORT_API GList* +decarta_geocode_list_append (GList *geocode_list, DecartaGeocode *geocode) +{ + g_return_val_if_fail (geocode, NULL); + return g_list_append (geocode_list, (gpointer)geocode); +} + +EXPORT_API +void decarta_geocode_list_free (GList *geocode_list) +{ + g_return_if_fail (geocode_list); + g_list_foreach(geocode_list, (GFunc)_geocode_list_free_gfunc, NULL); + g_list_free (geocode_list); +} + +EXPORT_API GList * +decarta_geocode_list_next (const GList *geocode_list, + const DecartaGeocode **geocode) +{ + g_return_val_if_fail (geocode_list, NULL); + g_return_val_if_fail (geocode, NULL); + *geocode = (DecartaGeocode*)geocode_list->data; + return g_list_next (geocode_list); +} + +EXPORT_API GList * +decarta_geocode_list_copy (const GList *geocode_list) +{ + g_return_val_if_fail (geocode_list, NULL); + GList *dup_geocode_list = NULL; + const DecartaGeocode *geocode = NULL; + geocode_list = decarta_geocode_list_next(geocode_list, &geocode); + while (geocode) { + dup_geocode_list = g_list_append (dup_geocode_list, decarta_geocode_copy (geocode)); + if (!geocode_list) break; + geocode_list = decarta_geocode_list_next(geocode_list, &geocode); + } + return dup_geocode_list; +} + +EXPORT_API DecartaMap * +decarta_map_new (const DecartaPosition *center, + const DecartaPosition *box_corner1, + const DecartaPosition *box_corner2, + const char *tile_url, + double radius) +{ + DecartaMap *map = g_new0 (DecartaMap, 1); + if (center) map->center = decarta_position_copy (center); + if (box_corner1) map->box_corner1 = decarta_position_copy (box_corner1); + if (box_corner2) map->box_corner2 = decarta_position_copy (box_corner2); + if (tile_url) map->tile_url = g_strdup (tile_url); + map->radius = radius; + return map ; +} + +EXPORT_API DecartaMap * +decarta_map_copy (const DecartaMap *map) +{ + g_return_val_if_fail (map, NULL); + return decarta_map_new (map->center, map->box_corner1, map->box_corner2, map->tile_url, map->radius); +} + +EXPORT_API void +decarta_map_free (DecartaMap *map) +{ + g_return_if_fail (map); + if (map->center) decarta_position_free (map->center); + if (map->box_corner1) decarta_position_free (map->box_corner1); + if (map->box_corner2) decarta_position_free (map->box_corner2); + if (map->tile_url) g_free (map->tile_url); + g_free (map); +} + +static void +_map_list_free_gfunc (gpointer data, + gpointer user_data) +{ + DecartaMap* map = (DecartaMap*)data; + decarta_map_free (map); +} + +EXPORT_API GList* +decarta_map_list_append (GList *map_list, DecartaMap *map) +{ + g_return_val_if_fail (map, NULL); + return g_list_append (map_list, (gpointer)map); +} + +EXPORT_API void +decarta_map_list_free (GList *map_list) +{ + g_return_if_fail (map_list); + g_list_foreach(map_list, (GFunc)_map_list_free_gfunc, NULL); + g_list_free (map_list); +} + +EXPORT_API GList * +decarta_map_list_next (const GList *map_list, + const DecartaMap** map) +{ + g_return_val_if_fail (map_list, NULL); + g_return_val_if_fail (map, NULL); + *map = (DecartaMap*)map_list->data; + return g_list_next (map_list); +} + +EXPORT_API GList * +decarta_map_list_copy (const GList *map_list) +{ + g_return_val_if_fail (map_list, NULL); + GList *dup_map_list = NULL; + const DecartaMap *map = NULL; + map_list = decarta_map_list_next(map_list, &map); + while (map) { + dup_map_list = g_list_append (dup_map_list, decarta_map_copy (map)); + if (!map_list) break; + map_list = decarta_map_list_next(map_list, &map); + } + return dup_map_list; +} + +EXPORT_API DecartaRoute * +decarta_route_new (const GList *start_geo_list, const GList *end_geo_list, + unsigned int total_time, + double total_distance, + const DecartaPosition *box_corner1, const DecartaPosition *box_corner2, + const DecartaMap *overview, + const GList *line_pos_list, + const GList *instructions_list) +{ + DecartaRoute *route = g_new0 (DecartaRoute, 1); + if (start_geo_list) route->start_geo_list = decarta_geocode_list_copy (start_geo_list); + if (end_geo_list) route->end_geo_list = decarta_geocode_list_copy (end_geo_list); + route->total_time = total_time; + route->total_distance = total_distance; + if (box_corner1) route->box_corner1 = decarta_position_copy (box_corner1); + if (box_corner2) route->box_corner2 = decarta_position_copy (box_corner2); + if (overview) route->overview = decarta_map_copy (overview); + if (line_pos_list) route->line_pos_list = decarta_position_list_copy (line_pos_list); + if (instructions_list) route->instructions_list = decarta_route_instructions_list_copy (instructions_list); + return route; +} + +EXPORT_API DecartaRoute * +decarta_route_copy (const DecartaRoute *route) +{ + g_return_val_if_fail (route, NULL); + return decarta_route_new (route->start_geo_list, route->end_geo_list, + route->total_time, route->total_distance, + route->box_corner1, route->box_corner2, route->overview, + route->line_pos_list, route->instructions_list); +} + +EXPORT_API void +decarta_route_free (DecartaRoute *route) +{ + g_return_if_fail (route); + if (route->start_geo_list) decarta_geocode_list_free (route->start_geo_list); + if (route->end_geo_list) decarta_geocode_list_free (route->end_geo_list); + if (route->box_corner1) decarta_position_free (route->box_corner1); + if (route->box_corner2) decarta_position_free (route->box_corner2); + if (route->line_pos_list) decarta_position_list_free (route->line_pos_list); + if (route->overview) decarta_map_free (route->overview); + if (route->instructions_list) decarta_route_instructions_list_free (route->instructions_list); + g_free (route); +} + + +EXPORT_API DecartaRouteInstructions* +decarta_route_instructions_new (const char *tour, + unsigned int duration, + double distance, + const char *instruction, + const DecartaMap *map) +{ + DecartaRouteInstructions *route_inst = g_new0 (DecartaRouteInstructions, 1); + if (tour) route_inst->tour = g_strdup (tour); + route_inst->duration = duration; + route_inst->distance = distance; + if (instruction) route_inst->instruction = g_strdup (instruction); + if (map) route_inst->map = decarta_map_copy (map); + return route_inst; +} + +EXPORT_API DecartaRouteInstructions * +decarta_route_instructions_copy (const DecartaRouteInstructions *route_inst) +{ + g_return_val_if_fail (route_inst, NULL); + return decarta_route_instructions_new (route_inst->tour, route_inst->duration, + route_inst->distance, route_inst->instruction, route_inst->map); +} + +EXPORT_API void +decarta_route_instructions_free (DecartaRouteInstructions *route_inst) +{ + g_return_if_fail (route_inst); + g_free (route_inst->tour); + g_free (route_inst->instruction); + decarta_map_free (route_inst->map); + g_free (route_inst); +} + +static void +_route_instructions_list_free_gfunc (gpointer data, + gpointer user_data) +{ + DecartaRouteInstructions* route_inst = (DecartaRouteInstructions*)data; + decarta_route_instructions_free (route_inst); +} + +EXPORT_API GList* +decarta_route_instructions_list_append (GList *route_inst_list, DecartaRouteInstructions *route_inst) +{ + g_return_val_if_fail (route_inst, NULL); + return g_list_append (route_inst_list, (gpointer)route_inst); +} + +EXPORT_API void +decarta_route_instructions_list_free (GList *route_inst_list) +{ + g_return_if_fail (route_inst_list); + g_list_foreach(route_inst_list, (GFunc)_route_instructions_list_free_gfunc, NULL); + g_list_free (route_inst_list); +} + +EXPORT_API GList * +decarta_route_instructions_list_next (const GList *route_inst_list, + const DecartaRouteInstructions** route_inst) +{ + g_return_val_if_fail (route_inst_list, NULL); + g_return_val_if_fail (route_inst, NULL); + *route_inst = (DecartaRouteInstructions*)route_inst_list->data; + return g_list_next (route_inst_list); +} + +EXPORT_API GList * +decarta_route_instructions_list_copy (const GList *route_inst_list) +{ + g_return_val_if_fail (route_inst_list, NULL); + GList *dup_route_inst_list = NULL; + const DecartaRouteInstructions *route_inst = NULL; + route_inst_list = decarta_route_instructions_list_next(route_inst_list, &route_inst); + while (route_inst) { + dup_route_inst_list = g_list_append (dup_route_inst_list, decarta_route_instructions_copy (route_inst)); + if (!route_inst_list) break; + route_inst_list = decarta_route_instructions_list_next(route_inst_list, &route_inst); + } + return dup_route_inst_list; +} + +EXPORT_API DecartaDirectoryRequest * +decarta_directory_request_new (const DecartaPOIPreference *pref, + DecartaDirectorySearchType search_type, + DecartaDirectoryType type, + const DecartaPosition *pos, + const DecartaAddress *addr, + const DecartaBoundary *bound, + const DecartaPOIProperty *property, + double distance, + guint request_id) +{ + DecartaDirectoryRequest* request = g_new0 (DecartaDirectoryRequest, 1); + request->search_type = search_type; + request->type = type; + if (type == DECARTA_DIRECTORY_TYPE_POS) request->pos = decarta_position_copy (pos); + else if (type == DECARTA_DIRECTORY_TYPE_ADDRESS) request->addr = decarta_addr_copy (addr); + else if (type == DECARTA_DIRECTORY_TYPE_BOUNDARY) request->boundary = decarta_boundary_copy (bound); + + request->property = decarta_poi_property_copy (property); + request->distance = distance; + request->pref = decarta_poi_preference_copy(pref); + if (!request->pref->item) request->pref->item = g_strdup("Distance"); //Distance is default. + + request->request_id = request_id; + return request; +} + +EXPORT_API void +decarta_directory_request_free (DecartaDirectoryRequest *request) +{ + g_return_if_fail (request); + if (request->type == DECARTA_DIRECTORY_TYPE_POS) decarta_position_free (request->pos); + else if (request->type == DECARTA_DIRECTORY_TYPE_ADDRESS) decarta_address_free (request->addr); + else if (request->type == DECARTA_DIRECTORY_TYPE_BOUNDARY) decarta_boundary_free(request->boundary); + decarta_poi_property_free (request->property); + decarta_poi_preference_free(request->pref); + g_free (request); +} + +EXPORT_API DecartaDirectoryRequest * +decarta_directory_request_copy (const DecartaDirectoryRequest *request) +{ + g_return_val_if_fail (request, NULL); + return decarta_directory_request_new (request->pref, request->search_type, request->type, request->pos, request->addr, request->boundary, request->property, request->distance, request->request_id); +} + +EXPORT_API DecartaRouteRequest * +decarta_route_request_new (DecartaRoutePreference pref, + const DecartaGeocode *start, const DecartaGeocode *end, + const GList *via_geocode_list, + gboolean pos_needed, + gboolean instructions_map_needed, + gboolean bbox_needed, + const DecartaPosition *bbox_pos1, + const DecartaPosition *bbox_pos2, + gboolean resolution_needed, + float resolution, + gboolean VR_needed, + guint request_id, + char *dist_unit, char *rules) +{ + g_return_val_if_fail (start, NULL); + g_return_val_if_fail (end, NULL); + g_return_val_if_fail (dist_unit, NULL); + DecartaRouteRequest *route_req = g_new0 (DecartaRouteRequest, 1); + route_req->pref = pref; + route_req->start = decarta_geocode_copy (start); + route_req->end = decarta_geocode_copy (end); + if (route_req->via_geocode_list) route_req->via_geocode_list = decarta_geocode_list_copy (via_geocode_list); + route_req->pos_needed = pos_needed; + route_req->instructions_map_needed = instructions_map_needed; + route_req->request_id = request_id; + + route_req->bbox_needed = bbox_needed; + route_req->bbox_pos1 = decarta_position_copy(bbox_pos1); + route_req->bbox_pos2 = decarta_position_copy(bbox_pos2); + route_req->resolution_needed = resolution_needed; + route_req->resolution = resolution; + route_req->VR_needed = VR_needed; + + route_req->dist_unit = g_strdup(dist_unit); + route_req->rules = g_strdup(rules); + return route_req; +} + +EXPORT_API DecartaRouteRequest * +decarta_route_request_copy (const DecartaRouteRequest *route_req) +{ + g_return_val_if_fail (route_req, NULL); + return decarta_route_request_new (route_req->pref, route_req->start, route_req->end, + route_req->via_geocode_list, route_req->pos_needed, route_req->instructions_map_needed, + route_req->bbox_needed, route_req->bbox_pos1, route_req->bbox_pos2, + route_req->resolution_needed, route_req->resolution, route_req->VR_needed, route_req->request_id, + route_req->dist_unit, route_req->rules); +} + +EXPORT_API void +decarta_route_request_free (DecartaRouteRequest *route_req) +{ + g_return_if_fail (route_req); + if (route_req->start) decarta_geocode_free (route_req->start); + if (route_req->end) decarta_geocode_free (route_req->end); + if (route_req->via_geocode_list) decarta_geocode_list_free (route_req->via_geocode_list); + if (route_req->bbox_pos1) decarta_position_free (route_req->bbox_pos1); + if (route_req->bbox_pos2) decarta_position_free (route_req->bbox_pos2); + g_free (route_req->dist_unit); + g_free (route_req->rules); + g_free (route_req); +} diff --git a/decarta/decarta_types.h b/decarta/decarta_types.h new file mode 100755 index 0000000..598f602 --- /dev/null +++ b/decarta/decarta_types.h @@ -0,0 +1,318 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_TYPES_H_ +#define _DECARTA_TYPES_H_ + +#include + +G_BEGIN_DECLS + +typedef enum { + DECARTA_ERROR_PARAMETER, + DECARTA_ERROR_XML, + DECARTA_ERROR_NOT_FOUND, + DECARTA_ERROR_HTTP, + DECARTA_ERROR_CONFIGURATION_FILE = -1, + DECARTA_ERROR_NONE = 0, +} DecartaError; + +typedef struct +{ + double latitude; + double longitude; +} DecartaPosition; + +typedef struct{ + char *street_number; + char *street_name; + char *state; // Country Subdivision + char *county; // Country Secondary Subdivision + char *city; // Municipality + char *district; // Municipality Subdivision + char* postal_code; // Postal Code + char* landmark_type; // type of landmark (e.g. Restaurant) + char* landmark_name; // landmark := POI name +} DecartaFormedAddress; + +typedef struct{ + char *country_code; + char *language_code; + gboolean is_freerorm; + union { + char* freeform_address; + DecartaFormedAddress *formed_addr; + }; +} DecartaAddress; + +typedef enum { + DECARTA_BOUNDARY_NONE = 0, ///< Undefined geographical area type. + DECARTA_BOUNDARY_RECT, ///< Rectangular geographical area type. + DECARTA_BOUNDARY_CIRCLE, ///< Circle geographical area type. + DECARTA_BOUNDARY_POLYGON ///< Polygon geographical area type. +} DecartaBoundaryType; + +/** + * @brief This represents a rectangular geographical area. + */ +typedef struct { + DecartaPosition* left_top; ///< The left top position of rectangle. + DecartaPosition* right_bottom; ///< The right bottom position of rectangle. +} DecartaRect; + +/** + * @brief This represents a circle geographical area with center geographic position and radius. + */ +typedef struct { + DecartaPosition* center; ///< The center position of a circle. + gdouble radius; ///< The radius of a circle. +} DecartaCircle; + +/** + * @brief This represents a polygon geographical area. + */ +typedef struct { + GList *position_list; ///< The collection of positions +} DecartaPolygon; + +typedef struct { + DecartaBoundaryType type; ///< The boundary type of this information. + union { + DecartaRect rect; ///< The geographical information of a rectangle. + DecartaCircle circle; ///< The geographical information of a circle. + DecartaPolygon polygon; ///< The geographical information of a polygon. + }; +} DecartaBoundary; + + +typedef struct { + DecartaPosition *pos; + DecartaAddress *addr; +} DecartaGeocode; + +typedef struct { + DecartaPosition *center; + DecartaPosition *box_corner1; // opposite corners of the bounding rectangle + DecartaPosition *box_corner2; // opposite corners of the bounding rectangle + char *tile_url; + double radius; +} DecartaMap; + +typedef enum { + DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST = 0, + DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE, + DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS, + DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_BOUNDARY +} DecartaDirectorySearchType; + +typedef enum { + DECARTA_DIRECTORY_TYPE_POS = 0, + DECARTA_DIRECTORY_TYPE_ADDRESS, + DECARTA_DIRECTORY_TYPE_BOUNDARY +} DecartaDirectoryType; + +typedef struct { + GHashTable* table; + GHashTableIter iter; +} DecartaPOIInfoTable; + +typedef struct{ + char* name; + char* id; + char* phone_number; + DecartaPOIInfoTable* info_list; + DecartaPosition *pos; + DecartaAddress *addr; + double distance; +} DecartaPOI; + +typedef struct{ + char* poi_name; + char* keyword; + char* brand; + char* type; + char* description; + char* URL; +} DecartaPOIProperty; + +typedef enum { + DECARTA_POI_PREF_SO_NONE, ///< None of sorting the results in order. + DECARTA_POI_PREF_SO_ASC, ///< A constant for sorting the results in ascending order + DECARTA_POI_PREF_SO_DESC ///< A constant for sorting the results in descending order +} DecartaPOIPrefSortOrder; + +typedef struct{ + guint max_result_cnt; ///< Maximum number of results + DecartaPOIPrefSortOrder sort_order; ///< Sort order + gchar *item; ///< Sory by item +} DecartaPOIPreference; + +typedef struct{ + DecartaDirectorySearchType search_type; + DecartaDirectoryType type; + union { + DecartaPosition *pos; + DecartaAddress *addr; + DecartaBoundary *boundary; + }; + DecartaPOIProperty *property; + double distance; + DecartaPOIPreference *pref; + guint request_id; +} DecartaDirectoryRequest; + +typedef enum { + DECARTA_ROUTE_PREF_NONE = 0, + DECARTA_ROUTE_PREF_FASTEST, + DECARTA_ROUTE_PREF_SHORTEST, + DECARTA_ROUTE_PREF_PEDESTRIAN, + DECARTA_ROUTE_PREF_AVOID_FREEWAYS, + DECARTA_ROUTE_PREF_NO_FREEWAYS, + DECARTA_ROUTE_PREF_MORE_FREEWAYS, + DECARTA_ROUTE_PREF_IGNORE_PIPES, + DECARTA_ROUTE_PREF_EASY +} DecartaRoutePreference; + +typedef struct { + DecartaRoutePreference pref; + DecartaGeocode *start; + DecartaGeocode *end; + GList *via_geocode_list; + gboolean pos_needed; + gboolean instructions_map_needed; + gboolean resolution_needed; /**< Resolution */ + float resolution; + gboolean VR_needed; /**< Vector Reduction */ + gboolean bbox_needed; /**< bounding box */ + DecartaPosition *bbox_pos1; + DecartaPosition *bbox_pos2; + guint request_id; + char *dist_unit; + char *rules; +} DecartaRouteRequest; + +typedef struct { + char *tour; // Which way point this maneuver is associated within an optimized route + unsigned int duration; // The time estimated to cover this route maneuver (seconds) + double distance; // The surface distance covered in this route maneuver + char *instruction; // A human readable instruction of this route maneuver + DecartaMap *map; // Map data for this instruction if exists +} DecartaRouteInstructions; + +typedef struct { + GList *start_geo_list; // start point candidate geocodes if exists + GList *end_geo_list; // end point candidate geocodes if exists + unsigned int total_time; // seconds + double total_distance; // The total distance traveled along the entire route (meters) + DecartaPosition *box_corner1; // opposite corners of the bounding rectangle + DecartaPosition *box_corner2; // opposite corners of the bounding rectangle + DecartaMap *overview; // Overview map data for entire route + GList *line_pos_list; // route positions if exists + GList *instructions_list; // route instructions if exists +} DecartaRoute; + +DecartaPosition *decarta_position_new (double latitude, double longitude); +DecartaPosition *decarta_position_copy (const DecartaPosition *pos); +void decarta_position_free (DecartaPosition *pos); +GList *decarta_position_list_append (GList *pos_list, DecartaPosition *pos); +void decarta_position_list_free (GList *pos_list); +GList *decarta_position_list_next (const GList *pos_list, const DecartaPosition** pos); +GList *decarta_position_list_copy (const GList *pos_list); + +DecartaFormedAddress *decarta_formed_address_new (const char *street_number, const char *street_name, const char *state, const char *county, const char *city, const char *district, const char* postal_code, const char* landmark_type, const char* landmark_name); +DecartaFormedAddress *decarta_formed_address_copy (const DecartaFormedAddress *formed_addr); +void decarta_formed_address_free (DecartaFormedAddress *formed_addr); + +DecartaAddress *decarta_address_new (const char *country_code, const char *language_code, gboolean is_freerorm, const char *freeform_address, const DecartaFormedAddress *formed_addr); +DecartaAddress *decarta_addr_copy (const DecartaAddress *addr); +void decarta_address_free (DecartaAddress *addr); + +DecartaBoundary *decarta_boundary_new_for_rect (DecartaPosition *left_top, DecartaPosition *right_bottom); +DecartaBoundary *decarta_boundary_new_for_circle (DecartaPosition *center, gdouble radius); +DecartaBoundary *decarta_boundary_new_for_polygon(GList *position_list); +void decarta_boundary_free (DecartaBoundary *boundary); +DecartaBoundary *decarta_boundary_copy (const DecartaBoundary* boundary); +gboolean decarta_boundary_if_inside (DecartaBoundary* boundary, const DecartaPosition* position); + +DecartaPOI *decarta_poi_new (const char *name, const char* id, const char* phone_number, const DecartaPOIInfoTable* info_list, const DecartaPosition *pos, const DecartaAddress *addr, double distance); +DecartaPOI *decarta_poi_copy (const DecartaPOI *poi); +void decarta_poi_free (DecartaPOI *poi); +GList *decarta_poi_list_append (GList *poi_list, DecartaPOI *poi); +void decarta_poi_list_free (GList *poi_list); +GList *decarta_poi_list_next (const GList *poi_list, const DecartaPOI **poi); +GList *decarta_poi_list_copy (const GList *poi_list); + +DecartaPOIInfoTable *decarta_poi_info_table_new (void); +void decarta_poi_info_table_free (DecartaPOIInfoTable* poi_info_list); +gboolean decarta_poi_info_table_insert (DecartaPOIInfoTable* poi_info_list, const gchar* name, const gchar* value); +gboolean decarta_poi_info_table_iter_init (DecartaPOIInfoTable* poi_info_list); +gboolean decarta_poi_info_list_table_next (DecartaPOIInfoTable* poi_info_list, gchar** name, gchar** value); +DecartaPOIInfoTable *decarta_poi_info_table_copy (const DecartaPOIInfoTable *poi_info_list); + +DecartaPOIProperty *decarta_poi_property_new (const char* poi_name, const char* keyword, const char* brand, const char* type, const char* description, const char* URL); +DecartaPOIProperty *decarta_poi_property_copy (const DecartaPOIProperty *property); +void decarta_poi_property_free (DecartaPOIProperty *property); + +DecartaPOIPreference *decarta_poi_preference_new (guint max_result_cnt, DecartaPOIPrefSortOrder sort_order, const gchar *item); +void decarta_poi_preference_free (DecartaPOIPreference *preference); +DecartaPOIPreference *decarta_poi_preference_copy (const DecartaPOIPreference *preference); + +DecartaGeocode *decarta_geocode_new (const DecartaPosition *pos, const DecartaAddress *addr); +DecartaGeocode *decarta_geocode_copy (const DecartaGeocode *geocode); +void decarta_geocode_free (DecartaGeocode *geocode); +GList *decarta_geocode_list_append (GList *geocode_list, DecartaGeocode *geocode); +void decarta_geocode_list_free (GList *geocode_list); +GList *decarta_geocode_list_next (const GList *geocode_list, const DecartaGeocode **geocode); +GList *decarta_geocode_list_copy (const GList *geocode_list); + +DecartaMap *decarta_map_new (const DecartaPosition *pos, const DecartaPosition *box_corner1, const DecartaPosition *box_corner2, const char *tile_url, double radius); +DecartaMap *decarta_map_copy (const DecartaMap *map); +void decarta_map_free (DecartaMap *map); +GList *decarta_map_list_append (GList *map_list, DecartaMap *map); +void decarta_map_list_free (GList *map_list); +GList *decarta_map_list_next (const GList *map_list, const DecartaMap** map); +GList *decarta_map_list_copy (const GList *map_list); + +DecartaRoute *decarta_route_new (const GList *start_geo_list, const GList *end_geo_list, unsigned int total_time, double total_distance, const DecartaPosition *box_corner1, const DecartaPosition *box_corner2, const DecartaMap *overview, const GList *line_pos_list, const GList *instructions_list); +DecartaRoute *decarta_route_copy (const DecartaRoute *route); +void decarta_route_free (DecartaRoute *route); + +DecartaRouteInstructions *decarta_route_instructions_new (const char *tour, unsigned int duration, double distance, const char *instruction, const DecartaMap *map); +DecartaRouteInstructions *decarta_route_instructions_copy (const DecartaRouteInstructions *route_inst); +void decarta_route_instructions_free (DecartaRouteInstructions *route_inst); +GList *decarta_route_instructions_list_append (GList *route_inst_list, DecartaRouteInstructions *route_inst); +void decarta_route_instructions_list_free (GList *route_inst_list); +GList *decarta_route_instructions_list_next (const GList *route_inst_list, const DecartaRouteInstructions** route_inst); +GList *decarta_route_instructions_list_copy (const GList *route_inst_list); + +DecartaDirectoryRequest *decarta_directory_request_new (const DecartaPOIPreference *pref, DecartaDirectorySearchType search_type, DecartaDirectoryType type, const DecartaPosition *pos, const DecartaAddress *addr, const DecartaBoundary *bound, const DecartaPOIProperty *property, double distance, guint request_id); +DecartaDirectoryRequest *decarta_directory_request_copy (const DecartaDirectoryRequest *request); +void decarta_directory_request_free (DecartaDirectoryRequest *request); + +DecartaRouteRequest *decarta_route_request_new (DecartaRoutePreference pref, const DecartaGeocode *start, const DecartaGeocode *end, const GList *via_geocode_list, gboolean pos_needed, gboolean instructions_map_needed, + gboolean bbox_needed, const DecartaPosition *bbox_pos1, const DecartaPosition *bbox_pos2, gboolean resolution_needed, float resolution, gboolean VR_needed, guint request_id, char *dist_unit, char *rules); + +DecartaRouteRequest *decarta_route_request_copy (const DecartaRouteRequest *route_req); +void decarta_route_request_free (DecartaRouteRequest *route_req); + +G_END_DECLS + +#endif diff --git a/decarta/decarta_xml.h b/decarta/decarta_xml.h new file mode 100755 index 0000000..d034440 --- /dev/null +++ b/decarta/decarta_xml.h @@ -0,0 +1,51 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_XML_H_ +#define _DECARTA_XML_H_ + +#include + +#include "decarta_types.h" +#include "decarta_route.h" +#include "decarta_geocode.h" +#include "decarta_directory.h" +#include "decarta_maps.h" + +G_BEGIN_DECLS + +gboolean xml_route_request_get (const DecartaRouteRequest *request, char **xml_request, unsigned int *size); +gboolean xml_route_parse (const char* xml_response, DecartaRoute **route, char **req_id, char **error_code, char **message); + +gboolean xml_map_request_get (const DecartaPosition *pos, int zoom, char **xml_request, unsigned int *size); +gboolean xml_map_parse (const char* xml_response, DecartaMap **map); + +gboolean xml_reverse_geocode_request_get (const DecartaPosition *pos, char **xml_request, unsigned int *size); +gboolean xml_reverse_geocode_parse (const char* xml_response, DecartaGeocode** geocode); +gboolean xml_geocode_request_get (const DecartaAddress *addr, char **xml_request, unsigned int *size); +gboolean xml_geocode_parse (const char* xml_response, GList** geocode_list); + +gboolean xml_directory_request_get (const DecartaDirectoryRequest *request, char **xml_request, unsigned int *size); +gboolean xml_directory_parse (const char* xml_response, GList** poi_list, char **req_id, char **error_code, char **message); + +G_END_DECLS + +#endif diff --git a/decarta/decarta_xml_directory.c b/decarta/decarta_xml_directory.c new file mode 100755 index 0000000..871cdf7 --- /dev/null +++ b/decarta/decarta_xml_directory.c @@ -0,0 +1,261 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "decarta_log.h" +#include "xml_wrapper.h" +#include "decarta_xml.h" +#include "decarta_xml_internal.h" + +#define POI_CONTEXT "//"NS_XLS":POIContext[%d]" + +#define POI POI_CONTEXT"/"NS_XLS":POI" +#define POI_NAME POI"/@POIName" +#define POI_ID POI"/@ID" +#define POI_PHONENUMBER POI"/@phoneNumber" + +#define POI_INFO POI"/"NS_XLS":POIAttributeList/"NS_XLS":POIInfoList/"NS_XLS":POIInfo[%d]" +#define POI_INFO_NAME POI_INFO"/@name" +#define POI_INFO_VALUE POI_INFO"/@value" + +#define POI_DISTANCE POI_CONTEXT"/"NS_XLS":Distance" + + +static gboolean +make_xml_poi_location (XmlWriterHandler handle, + const DecartaDirectoryRequest *request) +{ + if (!xml_writer_all_start(handle, NS_XLS":POILocation", NULL, NULL)) return FALSE; + + if (request->search_type == DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST){ + if (!xml_writer_all_start(handle, NS_XLS":Nearest", NULL, NULL)) return FALSE; + } else if (request->search_type == DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE){ + if (!xml_writer_all_start(handle, NS_XLS":WithinDistance", NULL, NULL)) return FALSE; + } else if (request->search_type == DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS){ + // Address type added, needn't the NS_XLS":Address" keyword + } else if (request->search_type == DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_BOUNDARY){ + if (!xml_writer_all_start(handle, NS_XLS":WithinBoundary", NULL, NULL)) return FALSE; + } else { + DECARTA_LOGW("Invalid DecartaDirectorySearchType"); + return FALSE; + } + + if (request->type == DECARTA_DIRECTORY_TYPE_POS){ + if (!xml_writer_all_start(handle, NS_XLS":POI", NULL, "ID", "1", NULL)) return FALSE; + if (!xml_writer_all_start(handle, NS_GML":Point", NULL, NULL)) return FALSE; + if (!make_xml_position(handle, request->pos)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } else if(request->type == DECARTA_DIRECTORY_TYPE_ADDRESS){ + if (request->search_type == DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS) { + // Directory ADDRESS mode's address different with others, NOT "place" + if (!make_directory_addr_mode_xml_address(handle, request->addr)) return FALSE; + } else { + if (!make_xml_address(handle, request->addr)) return FALSE; + } + } else if(request->type == DECARTA_DIRECTORY_TYPE_BOUNDARY){ + if (!make_xml_boundary(handle, request->boundary)) return FALSE; + } else { + DECARTA_LOGW("Invalid DecartaDirectoryType"); + return FALSE; + } + if (request->search_type == DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE){ + char max_dist[256]; + g_snprintf(max_dist, 256, "%f", request->distance); + if(!xml_writer_all_start(handle, NS_XLS":MaximumDistance", NULL, "value", max_dist, "uom", DISTANCE_UINT, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; } + if (!xml_writer_end(handle)) return FALSE; + + if (request->search_type != DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS) { + // in directory ADDRESS mode, No this end toker + if (!xml_writer_end(handle)) return FALSE; + } + + if (request->property) { + if(!xml_writer_all_start(handle, NS_XLS":POIProperties", NULL, NULL)) return FALSE; + + if (!xml_writer_element_start(handle, NS_XLS":POIProperty")) return FALSE; + if (request->property->poi_name) { + if (!xml_writer_attribute_write(handle, "name", "POIName")) return FALSE; + if (!xml_writer_attribute_write(handle, "value", request->property->poi_name)) return FALSE; + } + if (request->property->keyword) { + if (!xml_writer_attribute_write(handle, "name", "Keyword")) return FALSE; + if (!xml_writer_attribute_write(handle, "value", request->property->keyword)) return FALSE; + } + if (request->property->brand) { + if (!xml_writer_attribute_write(handle, "name", "Brand")) return FALSE; + if (!xml_writer_attribute_write(handle, "value", request->property->brand)) return FALSE; + } + if (request->property->type) { + if (!xml_writer_attribute_write(handle, "name", "Type")) return FALSE; + if (!xml_writer_attribute_write(handle, "value", request->property->type)) return FALSE; + } + if (request->property->description) { + if (!xml_writer_attribute_write(handle, "name", "description")) return FALSE; + if (!xml_writer_attribute_write(handle, "value", request->property->description)) return FALSE; + } + if (request->property->URL) { + if (!xml_writer_attribute_write(handle, "name", "URL")) return FALSE; + if (!xml_writer_attribute_write(handle, "value", request->property->URL)) return FALSE; + } + if( !xml_writer_end(handle)) return FALSE; + if( !xml_writer_end(handle)) return FALSE; + } + return TRUE; +} + +gboolean +xml_directory_request_get (const DecartaDirectoryRequest *request, + char **xml_request, + unsigned int *size) +{ + if (!request || !request->pref || !request->pref->item || + !xml_request || !size) { + DECARTA_LOGW ("request or xml_request or size is NULL"); + return FALSE; + } + + char max_responses[32]; + if (g_snprintf (max_responses, 32, "%d", request->pref->max_result_cnt) < 0) return FALSE; + char request_id[32]; + // pass the request_id from the caller + if (g_snprintf (request_id, 32, "%d", request->request_id) < 0) return FALSE; + + if ((g_strcmp0(request->pref->item, "Name") != 0) && (g_strcmp0(request->pref->item, "Type") != 0) && + (g_strcmp0(request->pref->item, "Distance") != 0)) { + DECARTA_LOGW ("directory request's sort criteria string is wrong"); + return FALSE; + } + + gchar *sortDirection = NULL; + if (request->pref->sort_order == DECARTA_POI_PREF_SO_ASC) { + sortDirection = g_strdup("Ascending"); + } else if (request->pref->sort_order == DECARTA_POI_PREF_SO_DESC) { + sortDirection = g_strdup("Descending"); + } else { + DECARTA_LOGW ("set directory request's sort direction to ascending"); + sortDirection = g_strdup("Ascending"); + } + + gboolean ret = FALSE; + XmlWriterHandler handle = xml_writer_open("UTF-8"); + if (!handle) { + g_free(sortDirection); + sortDirection = NULL; + return FALSE; + } + if (make_xml_header(handle, "DirectoryRequest", max_responses, request_id) && + xml_writer_all_start(handle, NS_XLS":DirectoryRequest", NULL, "sortCriteria", request->pref->item, "sortDirection", sortDirection, NULL) && + make_xml_poi_location(handle, request) && + xml_writer_end(handle)) ret = TRUE; + else ret = FALSE; + if (!xml_writer_close(handle, xml_request, size)) ret = FALSE; + + if (sortDirection) { + g_free(sortDirection); + sortDirection = NULL; + } + return ret; +} + +gboolean +xml_directory_parse (const char* xml_response, + GList** poi_list, + char **req_id, + char **error_code, + char **message) +{ + DECARTA_LOGD ("xml_directory_parse"); + if (!xml_response || !poi_list || !req_id || !error_code || !message) { + DECARTA_LOGW ("xml_response or response is NULL"); + return FALSE; + } + XmlReaderHandler handle = xml_reader_open (xml_response, NS_XLS, NS_XLS_URI, NS_GML, NS_GML_URI, NULL); + if (!handle) return FALSE; + + int idx = 1; + *poi_list = NULL; + + if (parse_xml_request_id(handle, req_id)) { + DECARTA_LOGD ("xml_directory_parse req_id: [%s]", *req_id); + } + + char *severity = NULL; + if (parse_xml_error (handle, error_code, message, &severity)) { + DECARTA_LOGD ("xml_directory_parse %s: %s [%s]", *error_code, *message, severity); + g_free(severity); + xml_reader_close (handle); + return FALSE; + } + + while (1) { + char *name = NULL; + char *id = NULL; + char* phone_number = NULL; + DecartaPOIInfoTable *info_list = NULL; + DecartaPosition *pos = NULL; + DecartaAddress *addr = NULL; + double distance = 0; + + if (!xml_reader_is_valid (handle, POI_CONTEXT, idx)) break; + xml_reader_get_string(handle, &name, POI_NAME, idx); + xml_reader_get_string(handle, &id, POI_ID, idx); + xml_reader_get_string(handle, &phone_number, POI_PHONENUMBER, idx); + int idx2 = 1; + while (xml_reader_is_valid (handle, POI_INFO, idx, idx2)) { + info_list = decarta_poi_info_table_new (); + char *info_name = NULL; + char *info_val = NULL; + xml_reader_get_string(handle, &info_name, POI_INFO_NAME, idx, idx2); + xml_reader_get_string(handle, &info_val, POI_INFO_VALUE, idx, idx2); + decarta_poi_info_table_insert (info_list, info_name, info_val); + g_free(info_name); + g_free(info_val); + idx2++; + } + char *poi_prefix = g_strdup_printf(POI, idx); + pos = parse_xml_position(handle, poi_prefix, 1); + addr = parse_xml_address(handle, poi_prefix); + g_free(poi_prefix); + + char* distance_str = NULL; + xml_reader_get_string(handle, &distance_str, POI_DISTANCE, idx); + if (distance_str) { + distance = g_strtod (distance_str, NULL); + g_free (distance_str); + } + DecartaPOI *poi = decarta_poi_new (name, id, phone_number, info_list, pos, addr, distance); + g_free (name); + g_free (id); + g_free (phone_number); + decarta_poi_info_table_free (info_list); + decarta_position_free (pos); + decarta_address_free (addr); + *poi_list = decarta_poi_list_append (*poi_list, poi); + idx++; + } + xml_reader_close(handle); + return TRUE; +} diff --git a/decarta/decarta_xml_geocode.c b/decarta/decarta_xml_geocode.c new file mode 100755 index 0000000..2365345 --- /dev/null +++ b/decarta/decarta_xml_geocode.c @@ -0,0 +1,166 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "decarta_log.h" +#include "xml_wrapper.h" +#include "decarta_xml.h" +#include "decarta_xml_internal.h" + +#define REV_GEOCODE "//"NS_XLS":ReverseGeocodedLocation" +#define GEO_RESP "//"NS_XLS":GeocodeResponseList" +#define NUM_GEOCODE GEO_RESP"/@numberOfGeocodedAddresses" +#define GEOCODE GEO_RESP"/"NS_XLS":GeocodedAddress[%d]" + +gboolean +xml_reverse_geocode_request_get (const DecartaPosition *pos, + char **xml_request, + unsigned int *size) +{ + DECARTA_LOGD ("xml_reverse_geocode_request_get"); + if (!pos || !xml_request || !size) { + DECARTA_LOGW ("pos or xml_request or size is NULL"); + return FALSE; + } + gboolean ret = FALSE; + XmlWriterHandler handle = xml_writer_open("UTF-8"); + if (!handle) return FALSE; + if (make_xml_header(handle, "ReverseGeocodeRequest", NULL, NULL) && + xml_writer_all_start(handle, NS_XLS":ReverseGeocodeRequest", NULL, NULL) && + xml_writer_all_start(handle, NS_XLS":Position", NULL, NULL) && + xml_writer_all_start(handle, NS_GML":Point", NULL, NULL) && + make_xml_position (handle, pos) && + xml_writer_end(handle) && + xml_writer_end(handle) && + xml_writer_end(handle)) ret = TRUE; + else ret = FALSE; + if (!xml_writer_close(handle, xml_request, size)) ret = FALSE; + return ret; +} + +gboolean +xml_geocode_request_get (const DecartaAddress *addr, + char **xml_request, + unsigned int *size) +{ + DECARTA_LOGD ("xml_geocode_request_get"); + if (!addr || !xml_request || !size) { + DECARTA_LOGW ("addr or xml_request or size is NULL"); + return FALSE; + } + gboolean ret = FALSE; + XmlWriterHandler handle = xml_writer_open("UTF-8"); + if (!handle) return FALSE; + if (make_xml_header(handle, "GeocodeRequest", NULL, NULL) && + xml_writer_all_start(handle, NS_XLS":GeocodeRequest", NULL, NULL) && + make_xml_address (handle, addr) && + xml_writer_end(handle)) ret = TRUE; + else ret = FALSE; + if (!xml_writer_close(handle, xml_request, size)) ret = FALSE; + return ret; +} + +gboolean +xml_reverse_geocode_parse (const char* xml_response, + DecartaGeocode** geocode) +{ + DECARTA_LOGD ("xml_reverse_geocode_parse"); + if (!xml_response || !geocode) { + DECARTA_LOGW ("xml_response or geocode is NULL"); + return FALSE; + } + XmlReaderHandler handle = xml_reader_open (xml_response, NS_XLS, NS_XLS_URI, NS_GML, NS_GML_URI, NULL); + if (!handle) return FALSE; + + gboolean ret = TRUE; + char *error_code = NULL; + char *message = NULL; + char *severity = NULL; + if (parse_xml_error (handle, &error_code, &message, &severity)) { + g_free(error_code); + g_free(message); + g_free(severity); + xml_reader_close (handle); + return FALSE; + } + + *geocode = NULL; + if (xml_reader_is_valid (handle, REV_GEOCODE)) { + DecartaPosition *pos = parse_xml_position (handle, REV_GEOCODE, 1); + DecartaAddress *addr = parse_xml_address(handle, REV_GEOCODE); + *geocode = decarta_geocode_new (pos, addr); + decarta_position_free (pos); + decarta_address_free (addr); + } + xml_reader_close(handle); + return ret; +} + +gboolean +xml_geocode_parse (const char* xml_response, + GList** geocode_list) +{ + DECARTA_LOGD ("xml_geocode_parse"); + if (!xml_response || !geocode_list) { + DECARTA_LOGW ("xml_response or geocode_list is NULL"); + return FALSE; + } + XmlReaderHandler handle = xml_reader_open (xml_response, NS_XLS, NS_XLS_URI, NS_GML, NS_GML_URI, NULL); + if (!handle) return FALSE; + + *geocode_list = NULL; + char *error_code = NULL; + char *message = NULL; + char *severity = NULL; + if (parse_xml_error (handle, &error_code, &message, &severity)) { + g_free(error_code); + g_free(message); + g_free(severity); + xml_reader_close (handle); + return FALSE; + } + char *num_geocode_str = NULL; + if (!xml_reader_get_string(handle, &num_geocode_str, NUM_GEOCODE, NULL)) { + xml_reader_close(handle); + return FALSE; + } + int idx = 1; + int num_geocode = g_ascii_strtoll (num_geocode_str, NULL, 10); + for (idx = 1 ; idx <= num_geocode ; idx++) { + DecartaPosition *pos = NULL; + DecartaAddress *addr = NULL; + if (!xml_reader_is_valid (handle, GEOCODE, idx)) break; + + char *prefix = g_strdup_printf (GEOCODE, idx); + pos = parse_xml_position (handle, prefix, 1); + addr = parse_xml_address(handle, prefix); + g_free(prefix); + + *geocode_list = decarta_geocode_list_append (*geocode_list, decarta_geocode_new (pos, addr)); + decarta_position_free (pos); + decarta_address_free (addr); + } + xml_reader_close(handle); + return TRUE; +} diff --git a/decarta/decarta_xml_internal.c b/decarta/decarta_xml_internal.c new file mode 100755 index 0000000..057ae30 --- /dev/null +++ b/decarta/decarta_xml_internal.c @@ -0,0 +1,376 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "decarta_log.h" +#include "decarta_types.h" +#include "decarta_config.h" +#include "xml_wrapper.h" +#include "decarta_xml_internal.h" + +static const char* XLS_VERSION="1"; +static const char* XLS_LANG="en"; +static const char* XMLNS_URI_XLS="http://www.opengis.net/xls"; +static const char* XMLNS_URI_GML="http://www.opengis.net/gml"; +static const char* REQUEST_MAXIMUM_RESPONSES="25"; +static const char* REQUEST_VERSION="1.0"; +static const char* REQUEST_ID="10"; + +#define POINT_POS "/"NS_GML":Point/"NS_GML":pos" +#define POS "/"NS_GML":pos" + +#define ADDR_COUNTRY "/"NS_XLS":Address/@countryCode" +#define ADDR_LANGUAGE "/"NS_XLS":Address/@language" +#define ADDR_FREE "/"NS_XLS":Address/"NS_XLS":freeFormAddress" +#define ADDR_STREET_NUMBER "/"NS_XLS":Address/"NS_XLS":StreetAddress/"NS_XLS":Building/@number" +#define ADDR_STREET_NAME "/"NS_XLS":Address/"NS_XLS":StreetAddress/"NS_XLS":Street" +#define ADDR_STATE "/"NS_XLS":Address/"NS_XLS":Place[@type='CountrySubDivision']" +#define ADDR_COUNTY "/"NS_XLS":Address/"NS_XLS":Place[@type='CountrySecondarySubDivision']" +#define ADDR_CITY "/"NS_XLS":Address/"NS_XLS":Place[@type='Municipality']" +#define ADDR_DISTRICT "/"NS_XLS":Address/"NS_XLS":Place[@type='MunicipalitySubdivision']" +#define ADDR_POSTALCODE "/"NS_XLS":Address/"NS_XLS":PostalCode" +#define ADDR_LANDMARK_TYPE "/"NS_XLS":Address/"NS_XLS":Place[@type='Landmark']/@subType" +#define ADDR_LANDMARK_NAME "/"NS_XLS":Address/"NS_XLS":Place[@type='Landmark']" + +#define ERROR "//"NS_XLS":ErrorList/"NS_XLS":Error" +#define ERROR_CODE ERROR"/@errorCode" +#define ERROR_MSG ERROR"/@message" +#define ERROR_SEVERITY ERROR"/@severity" + +#define RESPONSE "//"NS_XLS":Response" +#define RESPONSE_REQ_ID RESPONSE"/@requestID" +#define RESPONSE_NUM_OF_RESP RESPONSE"/@numberOfResponses" +#define RESPONSE_VER RESPONSE"/@version" + + +DecartaPosition * +get_position_from_string (const char *pos_str) +{ + if (!pos_str || !strlen(pos_str)) return NULL; + char **pos_str_dup = g_strsplit_set (pos_str, " ", 2); + double latitude = g_ascii_strtod (pos_str_dup [0], NULL); + double longitude = g_ascii_strtod (pos_str_dup [1], NULL); + g_strfreev (pos_str_dup); + return decarta_position_new (latitude, longitude); +} + +gboolean +make_xml_header(XmlWriterHandler handle, const char* request_method, + const char* max_responses, const char* request_id) +{ + if (!handle || !request_method) return FALSE; + if (!xml_writer_all_start( handle, NS_XLS":XLS", NULL, + "version", XLS_VERSION, + NS_XLS":lang", XLS_LANG, + "xmlns:xls", XMLNS_URI_XLS, + "xmlns:gml", XMLNS_URI_GML, NULL)) return FALSE; + + gchar rand[128]; + g_snprintf(rand, 128, "%u", g_random_int()); + if(!xml_writer_all_start( handle, NS_XLS":RequestHeader", NULL, + "clientName", get_ID(), + "sessionID", rand, + "clientPassword", get_passwd(), + "configuration", get_conf(), NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + + if (!xml_writer_all_start( handle, NS_XLS":Request", NULL, + "maximumResponses", (!max_responses ? REQUEST_MAXIMUM_RESPONSES : max_responses), + "version", REQUEST_VERSION, + "requestID", (!request_id ? REQUEST_ID : request_id), + "methodName", request_method, NULL)) return FALSE; + return TRUE; +} + +gboolean +make_xml_position (XmlWriterHandler handle, + const DecartaPosition *pos) +{ + if(!handle || !pos) return FALSE; + char* pos_str = g_strdup_printf("%lf %lf", pos->latitude, pos->longitude); + if (!xml_writer_all_start(handle, NS_GML":pos", pos_str, NULL)) return FALSE; + g_free(pos_str); + if (!xml_writer_end(handle)) return FALSE; + return TRUE; +} + +gboolean +make_xml_point (XmlWriterHandler handle, + const char* prefix, + const DecartaGeocode *geo) +{ + if (!handle || !prefix || !geo) return FALSE; + if (!xml_writer_all_start(handle, prefix, NULL, NULL)) return FALSE; + if (geo->pos) { + if (!xml_writer_all_start(handle, NS_XLS":Position", NULL, NULL)) return FALSE; + if (!xml_writer_all_start(handle, NS_GML":Point", NULL, NULL)) return FALSE; + if (!make_xml_position (handle, geo->pos)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } else if (geo->addr) { + if (!make_xml_address (handle, geo->addr)) return FALSE; + } else return FALSE; + return TRUE; +} + + +gboolean +make_xml_address (XmlWriterHandler handle, + const DecartaAddress *addr) +{ + if (!handle || !addr) return FALSE; + if (!xml_writer_all_start( handle, NS_XLS":Address", NULL, "countryCode", addr->country_code, "language", addr->language_code, NULL)) return FALSE; + + if (addr->is_freerorm && addr->freeform_address) { + if (!xml_writer_all_start( handle, NS_XLS":freeFormAddress", addr->freeform_address, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } else{ + if (!addr->formed_addr) return FALSE; + if (!xml_writer_all_start( handle, NS_XLS":StreetAddress", NULL, NULL)) return FALSE; + if (!xml_writer_all_start( handle, NS_XLS":Building", NULL, "number", addr->formed_addr->street_number, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + + if (!xml_writer_all_start( handle, NS_XLS":Street", addr->formed_addr->street_name, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + + if (addr->formed_addr->state){ + if (!xml_writer_all_start( handle, NS_XLS":Place", addr->formed_addr->state, "type", "CountrySubdivision", NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } + if (addr->formed_addr->county){ + if (!xml_writer_all_start( handle, NS_XLS":Place", addr->formed_addr->county, "type", "CountrySecondarySubdivision", NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } + if (addr->formed_addr->city){ + if (!xml_writer_all_start( handle, NS_XLS":Place", addr->formed_addr->city, "type", "Municipality", NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } + if (addr->formed_addr->district){ + if (!xml_writer_all_start( handle, NS_XLS":Place", addr->formed_addr->district, "type", "MunicipalitySubdivision, NULL")) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } + if (addr->formed_addr->landmark_type && addr->formed_addr->landmark_name){ + if (!xml_writer_all_start( handle, NS_XLS":Place", addr->formed_addr->landmark_name, + "type", "Landmark", + "subType", addr->formed_addr->landmark_type, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } + if (addr->formed_addr->postal_code){ + if (!xml_writer_all_start( handle, NS_XLS":PostalCode", addr->formed_addr->postal_code, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } + } + if (!xml_writer_end(handle)) return FALSE; + + return TRUE; +} + +gboolean +make_directory_addr_mode_xml_address (XmlWriterHandler handle, + const DecartaAddress *addr) +{ + if (!handle || !addr) return FALSE; + if (!xml_writer_all_start( handle, NS_XLS":Address", NULL, "countryCode", addr->country_code, "language", addr->language_code, NULL)) return FALSE; + + if (addr->is_freerorm && addr->freeform_address) { + if (!xml_writer_all_start( handle, NS_XLS":freeFormAddress", addr->freeform_address, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } else{ + if (!addr->formed_addr) return FALSE; + if (!xml_writer_all_start( handle, NS_XLS":StreetAddress", NULL, NULL)) return FALSE; + if (!xml_writer_all_start( handle, NS_XLS":Building", NULL, "number", addr->formed_addr->street_number, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + + if (!xml_writer_all_start( handle, NS_XLS":Street", addr->formed_addr->street_name, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + + if (addr->formed_addr->postal_code){ + if (!xml_writer_all_start( handle, NS_XLS":PostalCode", addr->formed_addr->postal_code, NULL)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } + } + if (!xml_writer_end(handle)) return FALSE; + + return TRUE; +} + +gboolean +make_xml_position_xls (XmlWriterHandler handle, + const DecartaPosition *pos) +{ + if(!handle || !pos) return FALSE; + char* pos_str = g_strdup_printf("%lf %lf", pos->latitude, pos->longitude); + if (!xml_writer_all_start(handle, NS_XLS":pos", pos_str, NULL)) return FALSE; + g_free(pos_str); + if (!xml_writer_end(handle)) return FALSE; + return TRUE; +} + +gboolean +make_xml_boundary (XmlWriterHandler handle, + const DecartaBoundary *bound) +{ + if (!handle || !bound) return FALSE; + + if (bound->type == DECARTA_BOUNDARY_RECT) { + if (!xml_writer_all_start( handle, NS_XLS":AOI", NULL, "xmlns:gml", XMLNS_URI_GML, NULL)) return FALSE; + if (!xml_writer_all_start( handle, NS_XLS":Envelope", NULL, "xmlns:xls", XMLNS_URI_GML, NULL)) return FALSE; + + DecartaPosition *pos = g_new0(DecartaPosition, 1); + pos->latitude = bound->rect.left_top->latitude; + pos->longitude = bound->rect.left_top->longitude; + if (!make_xml_position_xls(handle, pos)) return FALSE; + pos->latitude = bound->rect.right_bottom->latitude; + pos->longitude = bound->rect.right_bottom->longitude; + if (!make_xml_position_xls(handle, pos)) return FALSE; + g_free(pos); + + if (!xml_writer_end(handle)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + } else if (bound->type == DECARTA_BOUNDARY_CIRCLE) { + } else if (bound->type == DECARTA_BOUNDARY_POLYGON) { + } + + return TRUE; +} + + +gboolean +parse_xml_error (XmlReaderHandler handle, + char **error_code, + char **message, + char **severity) +{ + if (!handle || !error_code || !message || !severity) { + DECARTA_LOGW ("handle or error_code or message or severity is NULL"); + return FALSE; + } + + if (xml_reader_is_valid (handle, ERROR)) { + xml_reader_get_string(handle, error_code, ERROR_CODE); + xml_reader_get_string(handle, message, ERROR_MSG); + xml_reader_get_string(handle, severity, ERROR_SEVERITY); + DECARTA_LOGW ("%s: %s [%s]", *error_code, *message, *severity); + return TRUE; + } + return FALSE; +} + +gboolean +parse_xml_request_id (XmlReaderHandler handle, + char **req_id) +{ + if (!handle || !req_id) { + DECARTA_LOGW ("handle or req_id is NULL"); + return FALSE; + } + if (xml_reader_is_valid (handle, RESPONSE)) { + xml_reader_get_string(handle, req_id, RESPONSE_REQ_ID); + DECARTA_LOGD ("Response req_id: %s", *req_id); + return TRUE; + } + DECARTA_LOGD ("Response can't read req_id!"); + return FALSE; +} + +DecartaPosition* +parse_xml_position (XmlReaderHandler handle, const char* prefix, int idx) +{ + if (!handle || !prefix) { + DECARTA_LOGW ("handle or prefix is NULL"); + return NULL; + } + DecartaPosition *pos = NULL; + char *pos_str = NULL; + if (!xml_reader_get_string (handle, &pos_str, "%s%s[%d]", prefix, POS, idx)) + xml_reader_get_string (handle, &pos_str, "%s%s[%d]", prefix, POINT_POS, idx); + if (pos_str) { + pos = get_position_from_string (pos_str); + g_free (pos_str); + } + return pos; +} + +DecartaAddress* +parse_xml_address (XmlReaderHandler handle, const char* prefix) +{ + if (!handle || !prefix) { + DECARTA_LOGW ("handle or prefix is NULL"); + return NULL; + } + DecartaAddress *addr = NULL; + DecartaFormedAddress *formed_addr = NULL; + char *free_addr = NULL; + char *country_code = NULL; + char *language_code = NULL; + char *street_number = NULL; + char *street_name = NULL; + char *state = NULL; + char *county = NULL; + char *city = NULL; + char *district = NULL; + char *postal_code = NULL; + char *landmark_type = NULL; + char *landmark_name = NULL; + gboolean is_freeformed = FALSE; + xml_reader_get_string(handle, &country_code, "%s%s", prefix, ADDR_COUNTRY); + xml_reader_get_string(handle, &language_code, "%s%s", prefix, ADDR_LANGUAGE); + + if (xml_reader_is_valid(handle, "%s%s", prefix, ADDR_FREE)) { + if (!xml_reader_get_string(handle, &free_addr, "%s%s", prefix, ADDR_FREE)) free_addr = NULL; + else is_freeformed = TRUE; + } else { + xml_reader_get_string(handle, &street_number, "%s%s", prefix, ADDR_STREET_NUMBER); + xml_reader_get_string(handle, &street_name, "%s%s", prefix, ADDR_STREET_NAME); + xml_reader_get_string(handle, &state, "%s%s", prefix, ADDR_STATE); + xml_reader_get_string(handle, &county, "%s%s", prefix, ADDR_COUNTY); + xml_reader_get_string(handle, &city, "%s%s", prefix, ADDR_CITY); + xml_reader_get_string(handle, &district, "%s%s", prefix, ADDR_DISTRICT); + xml_reader_get_string(handle, &postal_code, "%s%s", prefix, ADDR_POSTALCODE); + xml_reader_get_string(handle, &landmark_type, "%s%s", prefix, ADDR_LANDMARK_TYPE); + xml_reader_get_string(handle, &landmark_name, "%s%s", prefix, ADDR_LANDMARK_NAME); + formed_addr = decarta_formed_address_new (street_number, street_name, state, county, city, district, postal_code, landmark_type, landmark_name); + } + + addr = decarta_address_new (country_code, language_code, is_freeformed, free_addr, formed_addr); + g_free (free_addr); + g_free (country_code); + g_free (language_code); + g_free (street_number); + g_free (street_name); + g_free (state); + g_free (county); + g_free (city); + g_free (district); + g_free (postal_code); + g_free (landmark_type); + g_free (landmark_name); + if (formed_addr) decarta_formed_address_free (formed_addr); + return addr; +} + diff --git a/decarta/decarta_xml_internal.h b/decarta/decarta_xml_internal.h new file mode 100755 index 0000000..a00978a --- /dev/null +++ b/decarta/decarta_xml_internal.h @@ -0,0 +1,64 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _DECARTA_XML_INTERNAL_H_ +#define _DECARTA_XML_INTERNAL_H_ + +#include +#include "xml_wrapper.h" +#include "decarta_types.h" + + +G_BEGIN_DECLS + +#define NS_XLS "xls" +#define NS_XLS_URI "http://www.opengis.net/xls" + +#define NS_GML "gml" +#define NS_GML_URI "http://www.opengis.net/gml" + +#define DISTANCE_UINT "M" +#define TILE_SIZE "256" +#define IMG_FORMAT "PNG" + +DecartaPosition *get_position_from_string (const char *pos_str); + +gboolean make_xml_header(XmlWriterHandler handle, const char* request_method, const char* max_responses, const char* request_id); +gboolean make_xml_position(XmlWriterHandler handle, const DecartaPosition *pos); +gboolean make_xml_point (XmlWriterHandler handle, const char* prefix, const DecartaGeocode *geo); +gboolean make_xml_address(XmlWriterHandler handle, const DecartaAddress *addr); + +gboolean make_directory_addr_mode_xml_address(XmlWriterHandler handle, const DecartaAddress *addr); + +gboolean make_xml_boundary (XmlWriterHandler handle, const DecartaBoundary *bound); + +gboolean parse_xml_error (XmlReaderHandler handle, char **error_code, char **message, char **severity); + + +gboolean parse_xml_request_id (XmlReaderHandler handle, char **req_id); + +DecartaPosition *parse_xml_position (XmlReaderHandler handle, const char* prefix, int idx); +DecartaAddress *parse_xml_address (XmlReaderHandler handle, const char* prefix); + + +G_END_DECLS + +#endif diff --git a/decarta/decarta_xml_maps.c b/decarta/decarta_xml_maps.c new file mode 100755 index 0000000..6f59633 --- /dev/null +++ b/decarta/decarta_xml_maps.c @@ -0,0 +1,132 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "decarta_log.h" +#include "xml_wrapper.h" +#include "decarta_xml.h" +#include "decarta_xml_internal.h" + +static const char *SRS = "WGS-84"; +static const char *RADIUS_UNIT = "KM"; +static const char *RADIUS = "4"; +static const char *TILE_GRID_ROW = "1"; +static const char *TILE_GRID_COL = "1"; + +#define MAP_BOUNDING "//"NS_XLS":PortrayMapResponse/"NS_XLS":Map/"NS_XLS":BBoxContext" +#define MAP_GRID "//"NS_XLS":PortrayMapResponse/"NS_XLS":TileGrid[1]" +#define MAP_GRID_TILE_URL MAP_GRID"/"NS_XLS":Tile/"NS_XLS":Map/"NS_XLS":Content/"NS_XLS":URL" +#define MAP_GRID_CENTER MAP_GRID"/"NS_XLS":CenterContext" +#define MAP_GRID_CENTER_POS MAP_GRID_CENTER"/"NS_XLS":CenterPoint" +#define MAP_GRID_CENTER_RADIUS MAP_GRID_CENTER"/"NS_XLS":Radius" + +EXPORT_API gboolean +xml_map_request_get (const DecartaPosition *pos, + int zoom, + char **xml_request, + unsigned int *size) +{ + DECARTA_LOGD ("xml_map_request_get"); + if (!pos || !xml_request || !size) { + DECARTA_LOGW ("pos or xml_request or size is NULL"); + return FALSE; + } + gboolean ret = FALSE; + XmlWriterHandler handle = xml_writer_open("UTF-8"); + if (!handle) return FALSE; + char zoom_str[32]; + if (g_snprintf (zoom_str, 32, "zoom=%d", zoom) < 0) return FALSE; + if (make_xml_header(handle, "PortrayMapRequest", NULL, NULL) && + xml_writer_all_start(handle, NS_XLS":PortrayMapRequest", NULL, NULL) && + xml_writer_all_start(handle, NS_XLS":Output", NULL, "height", TILE_SIZE, "width", TILE_SIZE, "format", IMG_FORMAT, + "fixedgrid", "true", "useCache", "true", NULL) && + xml_writer_all_start(handle, NS_XLS":CenterContext", NULL, "SRS", SRS, NULL) && + xml_writer_all_start(handle, NS_XLS":CenterPoint", NULL, NULL) && + make_xml_position (handle, pos) && + xml_writer_end(handle) && + xml_writer_all_start(handle, NS_XLS":Radius", RADIUS, "unit", RADIUS_UNIT, NULL) && + xml_writer_end(handle) && + xml_writer_end(handle) && + xml_writer_all_start(handle, NS_XLS":TileGrid", NULL, "rows", TILE_GRID_ROW, "columns", TILE_GRID_COL, NULL) && + xml_writer_all_start(handle, NS_XLS":GridLayer", NULL, "name", "deCarta", "columns", TILE_GRID_COL, NULL) && + xml_writer_end(handle) && + xml_writer_all_start(handle, NS_XLS":GridLayer", NULL, "name", "globexplorer", "meta-inf", zoom_str, NULL) && + xml_writer_end(handle)) ret = TRUE; + else ret = FALSE; + if (!xml_writer_close(handle, xml_request, size)) ret = FALSE; + return ret; +} + +gboolean +xml_map_parse (const char* xml_response, + DecartaMap **map) +{ + DECARTA_LOGD ("xml_map_parse"); + if (!xml_response || !map) { + DECARTA_LOGW ("xml_response or geocode is NULL"); + return FALSE; + } + XmlReaderHandler handle = xml_reader_open (xml_response, NS_XLS, NS_XLS_URI, NS_GML, NS_GML_URI, NULL); + if (!handle) return FALSE; + + char *error_code = NULL; + char *message = NULL; + char *severity = NULL; + if (parse_xml_error (handle, &error_code, &message, &severity)) { + g_free(error_code); + g_free(message); + g_free(severity); + xml_reader_close (handle); + return FALSE; + } + + *map = NULL; + DecartaPosition *center = NULL; + DecartaPosition *box_corner1 = NULL; + DecartaPosition *box_corner2 = NULL; + char *tile_url = NULL; + double radius = 0; + + if (xml_reader_is_valid (handle, MAP_BOUNDING)) { + box_corner1 = parse_xml_position (handle, MAP_BOUNDING, 1); + box_corner2 = parse_xml_position (handle, MAP_BOUNDING, 2); + } + if (xml_reader_is_valid (handle, MAP_GRID)) { + xml_reader_get_string (handle, &tile_url, MAP_GRID_TILE_URL, NULL); + center = parse_xml_position (handle, MAP_GRID_CENTER_POS, 1); + char *radius_str = NULL; + if (xml_reader_get_string(handle, &radius_str, MAP_GRID_CENTER_RADIUS, NULL)) { + radius = g_strtod (radius_str, NULL); + g_free (radius_str); + } + } + *map = decarta_map_new (center, box_corner1, box_corner2, tile_url, radius); + if (center) decarta_position_free (center); + if (box_corner1) decarta_position_free (box_corner1); + if (box_corner2) decarta_position_free (box_corner2); + g_free (tile_url); + + xml_reader_close(handle); + return TRUE; +} diff --git a/decarta/decarta_xml_route.c b/decarta/decarta_xml_route.c new file mode 100755 index 0000000..3c276c3 --- /dev/null +++ b/decarta/decarta_xml_route.c @@ -0,0 +1,568 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "decarta_log.h" +#include "xml_wrapper.h" +#include "decarta_xml.h" +#include "decarta_xml_internal.h" + +static char* +get_route_pref (DecartaRoutePreference pref) +{ + char *ret = NULL; + if (pref == DECARTA_ROUTE_PREF_FASTEST) ret = g_strdup ("fastest"); + else if (pref == DECARTA_ROUTE_PREF_SHORTEST) ret = g_strdup ("shortest"); + else if (pref == DECARTA_ROUTE_PREF_PEDESTRIAN) ret = g_strdup ("pedestrian"); + else if (pref == DECARTA_ROUTE_PREF_AVOID_FREEWAYS) ret = g_strdup ("AvoidFreeways"); + else if (pref == DECARTA_ROUTE_PREF_NO_FREEWAYS) ret = g_strdup ("NoFreeways"); + else if (pref == DECARTA_ROUTE_PREF_MORE_FREEWAYS) ret = g_strdup ("MoreFreeways"); + else if (pref == DECARTA_ROUTE_PREF_IGNORE_PIPES) ret = g_strdup ("IgnorePipes"); + else if (pref == DECARTA_ROUTE_PREF_EASY) ret = g_strdup ("easy"); + return ret; +} + +static unsigned int +get_time_from_string (const char* str) +{ + if (!str) return 0; + unsigned int time = 0; + + gchar **part = g_strsplit_set (str, "S", 2); + g_free (part[1]); + + gchar **part_s = g_strsplit_set (part[0], "M", 2); + g_free (part[0]); + time += g_ascii_strtoull (part_s[1], NULL, 10); + g_free (part_s[1]); + + gchar **part_m = g_strsplit_set (part_s[0], "H", 2); + g_free (part_s[0]); + time += (g_ascii_strtoull (part_m[1], NULL, 10)*60); + g_free (part_m[1]); + + gchar **part_h = g_strsplit_set (part_m[0], "DT", 2); + g_free (part_m[0]); + time += (g_ascii_strtoull (part_h[1], NULL, 10)*3600); + g_free (part_h[1]); + + gchar **part_d = g_strsplit_set (part_h[0], "P", 2); + g_free (part_h[0]); + time += (g_ascii_strtoull (part_d [1], NULL, 10)*3600*24); + g_free (part_d [1]); + g_free (part_d [0]); + return time; +} + +static gboolean +make_xml_waypoint_list (XmlWriterHandler handle, + const DecartaRouteRequest *request) +{ + if (!handle || !request || !request->start || !request->end) return FALSE; + + if (!xml_writer_all_start(handle, NS_XLS":WayPointList", NULL, NULL)) return FALSE; + if (!make_xml_point (handle, NS_XLS":StartPoint", request->start)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + + if (request->via_geocode_list) { + const DecartaGeocode *via = NULL; + GList *via_geocode_list = decarta_geocode_list_next (request->via_geocode_list, &via); + while (via) { + if (!make_xml_point(handle, NS_XLS":ViaPoint", via)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + if (!via_geocode_list) break; + via_geocode_list = decarta_geocode_list_next(via_geocode_list, &via); + } + } + if (!make_xml_point (handle, NS_XLS":EndPoint", request->end)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + if (!xml_writer_end(handle)) return FALSE; + return TRUE; +} + +gboolean +xml_route_request_get (const DecartaRouteRequest *request, + char **xml_request, + unsigned int *size) +{ + if (!request || !xml_request || !size) { + DECARTA_LOGW ("request or xml_request or size is NULL"); + return FALSE; + } + gboolean ret = FALSE; + XmlWriterHandler handle = xml_writer_open("UTF-8"); + char *pref_str = get_route_pref (request->pref); + if (!handle) { + g_free(pref_str); + return FALSE; + } + if (make_xml_header (handle, "DetermineRouteRequest", NULL, NULL) && + xml_writer_all_start (handle, NS_XLS":DetermineRouteRequest", NULL, "provideRouteHandle", "false", "distanceUnit", request->dist_unit, NULL) && + xml_writer_all_start (handle, NS_XLS":RoutePlan", NULL, NULL) && + xml_writer_all_start (handle, NS_XLS":RoutePreference", pref_str, NULL) && + xml_writer_end(handle) && + make_xml_waypoint_list (handle, request) && + xml_writer_end(handle)) { + ret = TRUE; + if (request->instructions_map_needed) { + if (!xml_writer_all_start (handle, NS_XLS":RouteInstructionsRequest", NULL, "rules", request->rules, NULL) || + !xml_writer_end(handle)) ret = FALSE; + } + if (request->pos_needed) { + if (request->resolution_needed && request->VR_needed) { + char resolution_str[32]; + if (g_snprintf (resolution_str, 32, "%f", request->resolution) < 0) ret = FALSE; + if (!xml_writer_all_start (handle, NS_XLS":RouteGeometryRequest", NULL, "resolution", resolution_str, "routeGeometryFormat", "VR", NULL)) ret = FALSE; + } else if (request->resolution_needed && (request->VR_needed == FALSE)) { + char resolution_str[32]; + if (g_snprintf (resolution_str, 32, "%f", request->resolution) < 0) ret = FALSE; + if (!xml_writer_all_start (handle, NS_XLS":RouteGeometryRequest", NULL, "resolution", resolution_str, NULL)) ret = FALSE; + } else if ((request->resolution_needed == FALSE) && request->VR_needed) { + if (!xml_writer_all_start (handle, NS_XLS":RouteGeometryRequest", NULL, "routeGeometryFormat", "VR", NULL)) ret = FALSE; + } else { + if (!xml_writer_all_start (handle, NS_XLS":RouteGeometryRequest", NULL, NULL)) ret = FALSE; + } + if (request->bbox_needed) { + if (!xml_writer_all_start (handle, NS_XLS":BoundingBox", NULL, NULL)) ret = FALSE; + if (!make_xml_position(handle, request->bbox_pos1)) ret = FALSE; + if (!make_xml_position(handle, request->bbox_pos2)) ret = FALSE; + if (!xml_writer_end(handle)) ret = FALSE; + } + if (!xml_writer_end(handle)) ret = FALSE; + } + if (request->instructions_map_needed) { + if (!xml_writer_all_start (handle, NS_XLS":RouteMapRequest", NULL, NULL) || + !xml_writer_all_start (handle, NS_XLS":Output", NULL, "width", "500", "height", "500", "style", "Overview", "format", IMG_FORMAT, NULL) || + !xml_writer_end(handle) || + !xml_writer_all_start (handle, NS_XLS":Output", NULL, "width", TILE_SIZE, "height", TILE_SIZE, "style", "Maneuver", "format", IMG_FORMAT, NULL) || + !xml_writer_end(handle) || + !xml_writer_end(handle)) ret = FALSE; + } + } else ret = FALSE; + if (!xml_writer_close(handle, xml_request, size)) ret = FALSE; + g_free (pref_str); + return ret; +} + +static void __route_geo_addr_list_free_cb (gpointer data) +{ + g_return_if_fail (data); + + decarta_geo_addr_s *addr_item = (decarta_geo_addr_s *)data; + if (addr_item->building_num) { + g_free(addr_item->building_num); + } + if (addr_item->country_2_subdivision) { + g_free(addr_item->country_2_subdivision); + } + if (addr_item->country_code) { + g_free(addr_item->country_code); + } + if (addr_item->country_subdivision) { + g_free(addr_item->country_subdivision); + } + if (addr_item->freeform_addr) { + g_free(addr_item->freeform_addr); + } + if (addr_item->landmark_name) { + g_free(addr_item->landmark_name); + } + if (addr_item->landmark_type) { + g_free(addr_item->landmark_type); + } + if (addr_item->lang_code) { + g_free(addr_item->lang_code); + } + if (addr_item->municipality) { + g_free(addr_item->municipality); + } + if (addr_item->municipality_subdivision) { + g_free(addr_item->municipality_subdivision); + } + if (addr_item->pos) { + g_free(addr_item->pos); + } + if (addr_item->postcode) { + g_free(addr_item->postcode); + } + if (addr_item->street) { + g_free(addr_item->street); + } +} + +static void __route_instruction_list_free_cb (gpointer data) +{ + g_return_if_fail (data); + + decarta_route_inst_str_s *inst_item = (decarta_route_inst_str_s *)data; + if (inst_item->duration) { + g_free(inst_item->duration); + } + if (inst_item->distance) { + g_free(inst_item->distance); + } + if (inst_item->tour) { + g_free(inst_item->tour); + } + if (inst_item->instruction) { + g_free(inst_item->instruction); + } + if (inst_item->description) { + g_free(inst_item->description); + } +} + +static void __route_map_list_free_cb (gpointer data) +{ + g_return_if_fail (data); + + decarta_route_map_str_s *map_item = (decarta_route_map_str_s *)data; + if (map_item->url) { + g_free(map_item->url); + } + if (map_item->description) { + g_free(map_item->description); + } + if (map_item->pos1) { + g_free(map_item->pos1); + } + if (map_item->pos2) { + g_free(map_item->pos2); + } +} + +static void __sax_parse_route(void *user_data, DecartaRoute **route) +{ + DECARTA_LOGD("_sax_parse_route enter "); + + if (!user_data || !route) { + DECARTA_LOGW ("user_data or route is NULL"); + return; + } + + *route = NULL; + GList *start_geo_list = NULL; + GList *end_geo_list = NULL; + unsigned int total_time = 0; + double total_distance = 0; + DecartaPosition *box_corner1 = NULL; + DecartaPosition *box_corner2 = NULL; + GList *line_pos_list = NULL; + GList *instructions_list = NULL; + DecartaMap *overview_map = NULL; + + /** geometry list*/ + sax_route_data_s *route_data = (sax_route_data_s *)user_data; + if (route_data->route_geometry_str) { + gchar **part = g_strsplit_set(route_data->route_geometry_str, ",", 0); + int n_route_geomoetry = 0; + GArray *garray = NULL; + garray = g_array_new(FALSE, FALSE, sizeof(long)); + if (garray) { + while (part[n_route_geomoetry]) { + long tmp_long = g_ascii_strtoll(part[n_route_geomoetry], NULL, 10); + g_array_append_val(garray, tmp_long); + n_route_geomoetry++; + } + g_strfreev(part); + + DECARTA_LOGD("verify the array:---------number[%d]----------\n", n_route_geomoetry); + int i = 0; + long prev_lat_l = 0; + long prev_lon_l = 0; + DecartaPosition *pos = NULL; + for (i = 0; i < n_route_geomoetry; i++) { + DECARTA_LOGD("No. [%d]", i); + if (i == 0) { + // save the geometry locations number + int n_geometry = g_array_index(garray, long, i); + DECARTA_LOGD(" the summary number of route geometry is [%d]\n", n_geometry); + } else if (i == 2) { + long lat_l = g_array_index(garray, long, i - 1); + long lon_l = g_array_index(garray, long, i); + prev_lat_l = lat_l; + prev_lon_l = lon_l; + double lat_d = ((double)lat_l) / 100000; + double lon_d = ((double)lon_l) / 100000; + DECARTA_LOGD("first lat [%.5f], lon [%.5f]\n", lat_d, lon_d); + + pos = decarta_position_new(lat_d, lon_d); + line_pos_list = decarta_position_list_append(line_pos_list, pos); + } else if ((i % 2) == 0) { + long lat_diff_l = g_array_index(garray, long, i - 1); + long lon_diff_l = g_array_index(garray, long, i); + DECARTA_LOGD("lat_diff_l [%ld], lon_diff_l [%ld]\n", lat_diff_l, lon_diff_l); + long lat_l = lat_diff_l + prev_lat_l; + long lon_l = lon_diff_l + prev_lon_l; + prev_lat_l = lat_l; + prev_lon_l = lon_l; + double lat_d = ((double)lat_l) / 100000; + double lon_d = ((double)lon_l) / 100000; + DECARTA_LOGD("lat [%.5f], lon [%.5f]\n", lat_d, lon_d); + + pos = decarta_position_new(lat_d, lon_d); + line_pos_list = decarta_position_list_append(line_pos_list, pos); + } + } + + g_array_free(garray, TRUE); + } + g_free(route_data->route_geometry_str); + route_data->route_geometry_str = NULL; + } + + /** total time*/ + if (route_data->route_totaltime_str) { + total_time = get_time_from_string(route_data->route_totaltime_str); + g_free(route_data->route_totaltime_str); + } + + /** total distance*/ + if (route_data->route_totaldist_str) { + total_distance = g_ascii_strtod(route_data->route_totaldist_str, NULL); + g_free(route_data->route_totaldist_str); + } + + /** box*/ + if (route_data->route_bbox_pos1_str) { + box_corner1 = get_position_from_string (route_data->route_bbox_pos1_str); + g_free (route_data->route_bbox_pos1_str); + } + if (route_data->route_bbox_pos2_str) { + box_corner2 = get_position_from_string (route_data->route_bbox_pos2_str); + g_free (route_data->route_bbox_pos2_str); + } + + /** StartAddressCandidates*/ + DecartaPosition *pos = NULL; + DecartaAddress *addr = NULL; + DecartaFormedAddress *formed_addr = NULL; + gboolean is_freeformed = FALSE; + GList *start_addr_list = g_list_first(route_data->route_start_addr_list); + while (start_addr_list) { + decarta_geo_addr_s *start_item = (decarta_geo_addr_s *)start_addr_list->data; + if (!start_item) { + DECARTA_LOGD("start_item NULL, break the start list loop\n"); + break; + } + if (start_item->pos) { + DECARTA_LOGD("start pos [%s]\n", start_item->pos); + pos = get_position_from_string(start_item->pos); + } + if (start_item->is_freeform) { + DECARTA_LOGD("start freeform address [%s]\n", start_item->freeform_addr); + is_freeformed = TRUE; + } else { + formed_addr = decarta_formed_address_new(start_item->building_num, start_item->street, start_item->country_subdivision, + start_item->country_2_subdivision, start_item->municipality, start_item->municipality_subdivision, + start_item->postcode, start_item->landmark_type, start_item->landmark_name); + } + addr = decarta_address_new(start_item->country_code, start_item->lang_code, is_freeformed, start_item->freeform_addr, formed_addr); + if (formed_addr) { + decarta_formed_address_free(formed_addr); + } + /** create the start address list */ + start_geo_list = decarta_geocode_list_append(start_geo_list, decarta_geocode_new(pos, addr)); + if (pos) { + decarta_position_free(pos); + } + if (addr) { + decarta_address_free(addr); + } + start_addr_list = g_list_next(start_addr_list); + } + + if (route_data->route_start_addr_list) { + g_list_free_full(route_data->route_start_addr_list, __route_geo_addr_list_free_cb); + route_data->route_start_addr_list = NULL; + } + + /** EndAddressCandidates*/ + pos = NULL; + addr = NULL; + formed_addr = NULL; + is_freeformed = FALSE; + GList *end_addr_list = g_list_first(route_data->route_end_addr_list); + while (end_addr_list) { + decarta_geo_addr_s *end_item = (decarta_geo_addr_s *)end_addr_list->data; + if (!end_item) { + DECARTA_LOGD("start_item NULL, break the end list loop\n"); + break; + } + if (end_item->pos) { + DECARTA_LOGD("end pos [%s]\n", end_item->pos); + pos = get_position_from_string(end_item->pos); + } + if (end_item->is_freeform) { + DECARTA_LOGD("end freeform address [%s]\n", end_item->freeform_addr); + is_freeformed = TRUE; + } else { + formed_addr = decarta_formed_address_new(end_item->building_num, end_item->street, end_item->country_subdivision, + end_item->country_2_subdivision, end_item->municipality, end_item->municipality_subdivision, + end_item->postcode, end_item->landmark_type, end_item->landmark_name); + } + addr = decarta_address_new(end_item->country_code, end_item->lang_code, is_freeformed, end_item->freeform_addr, formed_addr); + if (formed_addr) { + decarta_formed_address_free(formed_addr); + } + /** create the start address list */ + end_geo_list = decarta_geocode_list_append(end_geo_list, decarta_geocode_new (pos, addr)); + if (pos) { + decarta_position_free(pos); + } + if (addr) { + decarta_address_free(addr); + } + end_addr_list = g_list_next(end_addr_list); + } + + if (route_data->route_end_addr_list) { + g_list_free_full(route_data->route_end_addr_list, __route_geo_addr_list_free_cb); + route_data->route_end_addr_list = NULL; + } + + /** route overview*/ + DecartaPosition *box_corner1_02 = get_position_from_string(route_data->route_ov_pos1_str); + DecartaPosition *box_corner2_02 = get_position_from_string(route_data->route_ov_pos2_str); + overview_map = decarta_map_new(NULL, box_corner1_02, box_corner2_02, route_data->route_ov_tile_url_str, 0); + if (box_corner1_02) { + decarta_position_free (box_corner1_02); + } + if (box_corner2_02) { + decarta_position_free (box_corner2_02); + } + if (route_data->route_ov_tile_url_str) { + g_free(route_data->route_ov_tile_url_str); + } + + /** instruction*/ + unsigned int duration= 0; + double distance = 0; + DecartaMap *map = NULL; + GList *inst_list = g_list_first(route_data->route_inst_str_list); + while (inst_list) { + decarta_route_inst_str_s *inst_item = (decarta_route_inst_str_s *)inst_list->data; + if (!inst_item) { + DECARTA_LOGD("inst_item NULL, break the inst list loop\n"); + break; + } + if (inst_item->instruction) { + DECARTA_LOGD("instruction [%s]\n", inst_item->instruction); + } + + if (inst_item->duration) { + duration = get_time_from_string(inst_item->duration); + } + if (inst_item->distance) { + distance = g_ascii_strtod(inst_item->distance, NULL); + } + + /** find the description matched map item */ + GList *map_list = g_list_first(route_data->route_map_str_list); + while (map_list) { + decarta_route_map_str_s *map_item = (decarta_route_map_str_s *)map_list->data; + if (map_item) { + if (!g_strcmp0(inst_item->description, map_item->description)) { + DECARTA_LOGD("---------inst & map description matched---------\n"); + DecartaPosition *box_corner1_03 = get_position_from_string(map_item->pos1); + DecartaPosition *box_corner2_03 = get_position_from_string(map_item->pos2); + map = decarta_map_new(NULL, box_corner1_03, box_corner2_03, map_item->url, 0); + if (box_corner1_03) { + decarta_position_free (box_corner1_03); + } + if (box_corner2_03) { + decarta_position_free (box_corner2_03); + } + /** break when matched map_item found */ + break; + } + }else { + DECARTA_LOGD("map_item NULL \n"); + } + map_list = g_list_next(map_list); + } + + /** create the instruction list */ + instructions_list = decarta_route_instructions_list_append(instructions_list, decarta_route_instructions_new(inst_item->tour, duration, distance, inst_item->instruction, map)); + inst_list = g_list_next(inst_list); + } + + if (route_data->route_inst_str_list) { + g_list_free_full(route_data->route_inst_str_list, __route_instruction_list_free_cb); + route_data->route_inst_str_list = NULL; + } + + if (route_data->route_map_str_list) { + g_list_free_full(route_data->route_map_str_list, __route_map_list_free_cb); + route_data->route_map_str_list = NULL; + } + + /** decarta route*/ + *route = decarta_route_new(start_geo_list, end_geo_list, total_time, total_distance, box_corner1, box_corner2, overview_map, line_pos_list, instructions_list); +} + +gboolean +xml_route_parse (const char* xml_response, + DecartaRoute **route, + char **req_id, + char **error_code, + char **message) +{ + DECARTA_LOGD ("xml_route_parse"); + if (!xml_response || !route) { + DECARTA_LOGW ("xml_response or route is NULL"); + return FALSE; + } + + sax_route_data_s *route_data = g_new0(sax_route_data_s, 1); + if (route_data) { + _xml_sax_read(xml_response, route_data); + + /** check the error code & DetermineRouteResponse */ + if (route_data->has_error) { + *error_code = g_strdup(route_data->error_code_str); + *message = g_strdup(route_data->error_message_str); + + g_free(route_data->error_code_str); + g_free(route_data->error_message_str); + g_free(route_data->error_severity_str); + g_free(route_data); + return FALSE; + } + if (!route_data->has_route_resp) { + g_free(route_data); + return FALSE; + } + __sax_parse_route(route_data, route); + g_free(route_data); + } + + if (*route == NULL) { + DECARTA_LOGW("[ERROR]xml_route_parse: route is NULL"); + return FALSE; + } + + return TRUE; +} + diff --git a/decarta/http_wrapper.c b/decarta/http_wrapper.c new file mode 100755 index 0000000..973a2d9 --- /dev/null +++ b/decarta/http_wrapper.c @@ -0,0 +1,303 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "decarta_log.h" +#include "http_wrapper.h" + +#define GCONF_HTTP_PROXY_HOST "/system/http_proxy/host" +#define GCONF_HTTP_PROXY_PORT "/system/http_proxy/port" + +#define DECARTA_NUM_HTTP_CONNECTIONS 128 + +typedef struct { + HttpType type; + SoupSession* session; +} HttpWrapper; + +static char* get_proxy() +{ + char *host = NULL; + int port; + char* proxy_string = NULL; + +#if 0 //We should check why the previous member use gconf + GConfClient* gconf_client = gconf_client_get_default(); + if(gconf_client == NULL) + return NULL; + + host = gconf_client_get_string(gconf_client, GCONF_HTTP_PROXY_HOST, NULL); + if( host && *host){ + port = gconf_client_get_int(gconf_client, GCONF_HTTP_PROXY_PORT, NULL); + if(port) + proxy_string = g_strdup_printf("http://%s:%u", host, port); + else + proxy_string = g_strdup_printf("http://%s", host); + } + + g_free(host); + g_object_unref(gconf_client); +#else + + host = getenv("http_proxy"); + if (host == NULL) + return NULL; + + if (strncmp(host, "http://", 7)) { + proxy_string = g_strdup_printf("http://%s", host); + } else { + proxy_string = g_strdup_printf("%s", host); + } +#endif + + return proxy_string; +} + +static SoupSession* soup_create_session_async() +{ + SoupSession* session = NULL; + char* proxy_string = get_proxy(); + if (proxy_string == NULL){ + DECARTA_LOGD("\tNo proxy"); + session = soup_session_async_new_with_options ( + SOUP_SESSION_MAX_CONNS, DECARTA_NUM_HTTP_CONNECTIONS, + SOUP_SESSION_MAX_CONNS_PER_HOST, DECARTA_NUM_HTTP_CONNECTIONS, NULL); + }else{ + DECARTA_LOGD("\tProxy readed [%s]", proxy_string); + SoupURI* uri = soup_uri_new(proxy_string); + session = soup_session_async_new_with_options ( + SOUP_SESSION_PROXY_URI, uri, + SOUP_SESSION_MAX_CONNS, DECARTA_NUM_HTTP_CONNECTIONS, + SOUP_SESSION_MAX_CONNS_PER_HOST, DECARTA_NUM_HTTP_CONNECTIONS, NULL); + g_free(proxy_string); + soup_uri_free(uri); + } + return session; +} + + +static SoupSession* soup_create_session() +{ + SoupSession* session = NULL; + char* proxy_string = get_proxy(); + if (proxy_string == NULL){ + DECARTA_LOGD("\tNo proxy"); + session = soup_session_sync_new_with_options ( + SOUP_SESSION_MAX_CONNS, DECARTA_NUM_HTTP_CONNECTIONS, + SOUP_SESSION_MAX_CONNS_PER_HOST, DECARTA_NUM_HTTP_CONNECTIONS, NULL); + }else{ + DECARTA_LOGD("\tProxy readed [%s]", proxy_string); + SoupURI* uri = soup_uri_new(proxy_string); + session = soup_session_sync_new_with_options ( + SOUP_SESSION_PROXY_URI, uri, + SOUP_SESSION_MAX_CONNS, DECARTA_NUM_HTTP_CONNECTIONS, + SOUP_SESSION_MAX_CONNS_PER_HOST, DECARTA_NUM_HTTP_CONNECTIONS, NULL); + g_free(proxy_string); + soup_uri_free(uri); + } + return session; +} + + +static void soup_delete_session(SoupSession* session) +{ + if (session) { + g_object_unref (session); + DECARTA_LOGD("\tSoup session removed"); + }else + DECARTA_LOGW("\tSoup session already removed"); +} + +static SoupMessage* soup_create_msg(const char* send_data, int send_data_size, const char* host) +{ + if(!send_data || !host){ + DECARTA_LOGW("http or Sending data or host is NULL"); + return NULL; + } + + SoupMessage* msg = soup_message_new (SOUP_METHOD_POST, host); + if (!msg){ + DECARTA_LOGW("Soup message creation failed"); + return NULL; + } + soup_message_set_request(msg, "text/xml", SOUP_MEMORY_COPY, send_data, send_data_size); + soup_message_headers_append(msg->request_headers, "Content-Type", "text/xml"); + + return msg; +} + +static void soup_delete_msg(SoupMessage* msg) +{ + if(msg){ + g_object_unref(msg); + } +} + +static char* soup_msg_process(SoupMessage* msg) +{ + char* recv_data = NULL; + if(msg == NULL){ + DECARTA_LOGD("\tSoup message is NULL"); + return NULL; + } + if(msg->status_code != SOUP_STATUS_OK){ + DECARTA_LOGD("http response error [%d, %s]", msg->status_code, msg->reason_phrase); + return NULL; + } + recv_data = g_new0(char, msg->response_body->length + 1); + g_memmove(recv_data, msg->response_body->data, msg->response_body->length); + recv_data[msg->response_body->length] = 0; + return recv_data; +} + +typedef struct{ + HttpCallback callback; + void* user_data; +} HttpCBData; + +static void soup_callback(SoupSession * session, SoupMessage * msg, HttpCBData* http_cb_data) +{ + if(!session || !msg){ + DECARTA_LOGD("\thttp session or msg is NULL"); + if(http_cb_data && http_cb_data->callback) + http_cb_data->callback(FALSE, NULL, http_cb_data->user_data); + return; + } + + DECARTA_LOGD ("\tResponse[%d, %s]", msg->status_code, msg->reason_phrase); + + if (msg->status_code == SOUP_STATUS_CANCELLED) { + DECARTA_LOGD("http response cancelled"); + return; + } + if(msg->status_code != SOUP_STATUS_OK){ + DECARTA_LOGD("http response error [%d]", msg->status_code); + http_cb_data->callback(FALSE, NULL, http_cb_data->user_data); + return; + } + char* recv_data = g_new0(char, msg->response_body->length + 1); + g_memmove(recv_data, msg->response_body->data, msg->response_body->length); + recv_data[msg->response_body->length] = 0; + http_cb_data->callback(TRUE, recv_data, http_cb_data->user_data); + g_free(http_cb_data); +} + +gboolean http_send(HttpHandle handle, const char* send_data, const char* host, char** recv_data, HttpCallback cb, void* user_data) +{ + DECARTA_LOGD ("http_send: %s", host); + HttpWrapper* http = (HttpWrapper*)handle; + if(!http || !http->session|| !send_data || !host){ + DECARTA_LOGW("http or soup session or sending data or host or callback is NULL or http type is not sync"); + return FALSE; + } + int send_data_size = strlen(send_data); + SoupMessage* msg = soup_create_msg(send_data, send_data_size, host); + if(!msg) + return FALSE; + + int ret = FALSE; + switch(http->type) + { + case HTTP_TYPE_SYNC:{ + soup_session_send_message(http->session, msg); + char* soup_recv_data = soup_msg_process(msg); + soup_delete_msg(msg); + if( soup_recv_data && recv_data){ + *recv_data = g_memdup(soup_recv_data, strlen(soup_recv_data)); + ret = TRUE; + } + g_free(soup_recv_data); + break; + } + case HTTP_TYPE_ASYNC:{ + if(cb){ + HttpCBData* http_cb_data = g_new0(HttpCBData, 1); + http_cb_data->callback = cb; + http_cb_data->user_data = user_data; + soup_session_queue_message (http->session, msg, (SoupSessionCallback)soup_callback, http_cb_data); + ret = TRUE; + } + break; + } + default: + DECARTA_LOGD("Undefined http type"); + + } + return ret; +} + +gboolean http_abort(HttpHandle handle) +{ + HttpWrapper* http = (HttpWrapper*)handle; + if(http->session) + soup_session_abort (http->session); + + return TRUE; +} + +HttpHandle http_open (HttpType type) +{ + g_type_init(); + + HttpWrapper* http = g_new0(HttpWrapper, 1); + http->type = type; + http->session = NULL; + switch(http->type) + { + case HTTP_TYPE_SYNC:{ + http->session = soup_create_session(); + break; + } + case HTTP_TYPE_ASYNC:{ + http->session = soup_create_session_async(); + break; + } + default: + DECARTA_LOGW("\tError: undefined http type"); + http->session = NULL; + } + + if(!http->session){ + g_free(http); + http = NULL; + } + return http; +} + +void http_close (HttpHandle handle) +{ + HttpWrapper* http = (HttpWrapper*)handle; + if(!http){ + DECARTA_LOGW("http is NULL"); + return; + } + http_abort(http); + soup_delete_session(http->session); +} diff --git a/decarta/http_wrapper.h b/decarta/http_wrapper.h new file mode 100644 index 0000000..87e3e90 --- /dev/null +++ b/decarta/http_wrapper.h @@ -0,0 +1,47 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef _HTTP_WRAPPER_H_ +#define _HTTP_WRAPPER_H_ + +#include + +G_BEGIN_DECLS + +#define DECARTA_XML_REQUEST_LENGTH 1024 + +typedef void* HttpHandle; + +typedef enum { + HTTP_TYPE_SYNC = 0, + HTTP_TYPE_ASYNC +} HttpType; + +typedef void (*HttpCallback)(gboolean success, char* recv_data, void* user_data); + +gboolean http_send(HttpHandle handle, const char* send_data, const char* host, char** recv_data, HttpCallback cb, void* user_data); +gboolean http_abort(HttpHandle handle); +HttpHandle http_open (HttpType type); +void http_close (HttpHandle http); + +G_END_DECLS + +#endif diff --git a/decarta/xml_wrapper.c b/decarta/xml_wrapper.c new file mode 100755 index 0000000..97699fb --- /dev/null +++ b/decarta/xml_wrapper.c @@ -0,0 +1,1944 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "decarta_log.h" +#include "xml_wrapper.h" +#include "decarta_xml_internal.h" + +#define DECARTA_XML_LOG "DECARTA_XML_LOG" // if this environment value is "1", print out xml log + +typedef struct { + xmlTextWriterPtr writer; + xmlBufferPtr buf; +} XmlWriterWrapper; + +typedef struct { + xmlDocPtr doc; + xmlXPathContextPtr xpath_ctx; +} XmlReaderWrapper; + +XmlWriterHandler +xml_writer_open (char* encoding) +{ + if(!encoding){ + DECARTA_LOGW("encoding is NULL"); + return NULL; + } + XmlWriterWrapper* xml = g_new0(XmlWriterWrapper, 1); + + xml->buf = xmlBufferCreate(); + if(!xml->buf) { + DECARTA_LOGW("failed to xmlBufferCreate() failed"); + return NULL; + } + xml->writer = xmlNewTextWriterMemory(xml->buf, 0); + if (!xml->writer) { + DECARTA_LOGW("failed to xmlNewTextWriterMemory(0x%x) failed", xml->buf); + xmlBufferFree(xml->buf); + g_free(xml); + return NULL; + } + if( xmlTextWriterStartDocument(xml->writer, NULL, encoding, NULL) < 0 ){ + DECARTA_LOGW("failed to xmlTextWriterStartDocument(0x%x, NULL, %s, NULL)", xml->writer, encoding); + xmlFreeTextWriter(xml->writer); + xmlBufferFree(xml->buf); + g_free(xml); + return NULL; + } + return xml; +} + +gboolean +xml_writer_close (XmlWriterHandler handle, char **content, unsigned int *size) +{ + XmlWriterWrapper* xml = (XmlWriterWrapper*)handle; + if(!xml || !xml->buf ||!xml->writer){ + DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL"); + return FALSE; + } + if( xmlTextWriterEndDocument(xml->writer) < 0){ + DECARTA_LOGW("failed to xmlTextWriterEndDocument(0x%x)", xml->writer); + return FALSE; + } + xmlFreeTextWriter(xml->writer); + if (0 == g_strcmp0(g_getenv (DECARTA_XML_LOG), "1")) g_printf ("\nrequest: %s", (const char*)xml->buf->content); + if (content && size){ + if(xml->buf->content) { + *content = g_strdup((const char*)xml->buf->content); + *size = g_utf8_strlen(*content, 4096); + } else { + *content = NULL; + *size = 0; + } + } + xmlBufferFree(xml->buf); + g_free(xml); + return TRUE; +} + +gboolean +xml_writer_element_start (XmlWriterHandler handle, const char* element) +{ + XmlWriterWrapper* xml = (XmlWriterWrapper*)handle; + if(!xml || !xml->buf ||!xml->writer){ + DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL"); + return FALSE; + } + if(!element){ + DECARTA_LOGW("element is NULL"); + return FALSE; + } + xmlTextWriterPtr writer = xml->writer; + + if( xmlTextWriterStartElement(writer, BAD_CAST element) < 0 ){ + DECARTA_LOGW("failed to xmlTextWriterStartElement(0x%x, %s)", writer, element); + return FALSE; + } + return TRUE; +} + +gboolean +xml_writer_attribute_write (XmlWriterHandler handle, const gchar *name, const gchar *value) +{ + XmlWriterWrapper* xml = (XmlWriterWrapper*)handle; + if(!xml || !xml->buf ||!xml->writer){ + DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL"); + return FALSE; + } + xmlTextWriterPtr writer = xml->writer; + + if(xmlTextWriterWriteAttribute(writer, BAD_CAST name, BAD_CAST value) < 0 ){ + DECARTA_LOGW("failed to xmlTextWriterWriteAttribute(0x%x, %s, %s)", writer, name, value); + return FALSE; + } + return TRUE; +} + +gboolean +xml_writer_all_start (XmlWriterHandler handle, const char* element, const char* content, ...) +{ + XmlWriterWrapper* xml = (XmlWriterWrapper*)handle; + if(!xml || !xml->buf ||!xml->writer){ + DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL"); + return FALSE; + } + if(!element){ + DECARTA_LOGW("element is NULL"); + return FALSE; + } + xmlTextWriterPtr writer = xml->writer; + + if( xmlTextWriterStartElement(writer, BAD_CAST element) < 0 ){ + DECARTA_LOGW("failed to xmlTextWriterStartElement(0x%x, %s)", writer, element); + return FALSE; + } + + va_list ap; + char *attr = NULL; + char *val = NULL; + va_start(ap, content); + while( (attr = va_arg(ap, char*))!= NULL ){ + val = va_arg(ap, char*); + if(attr && val){ + if(xmlTextWriterWriteAttribute(writer, BAD_CAST attr, BAD_CAST val) < 0 ){ + DECARTA_LOGW("failed to xmlTextWriterWriteAttribute(0x%x, %s, %s)", writer, attr, val); + return FALSE; + } + } + } + va_end(ap); + + if(content){ + if(xmlTextWriterWriteFormatRaw(writer, content) < 0 ){ + DECARTA_LOGW("failed to xmlTextWriterWriteFormatRaw(%s, %s)", element, content); + return FALSE; + } + } + return TRUE; +} + + +gboolean +xml_writer_end (XmlWriterHandler handle) +{ + XmlWriterWrapper* xml = (XmlWriterWrapper*)handle; + if(!xml || !xml->buf ||!xml->writer){ + DECARTA_LOGW("XmlWriterHandler or buffer or writer is NULL"); + return FALSE; + } + xmlTextWriterPtr writer = xml->writer; + + if(xmlTextWriterFullEndElement(writer) < 0) { + DECARTA_LOGW("failed to xmlTextWriterFullEndElement(0x%x)", writer); + return FALSE; + } + return TRUE; +} + +static char * +remove_noise (const char *data) +{ + if (!data) return NULL; + char **split = g_strsplit (data, ":XLS>", 2); + char *dup = g_strconcat (split[0], ":XLS>", NULL); + g_strfreev (split); + return dup; +} + +XmlReaderHandler +xml_reader_open (const char* data, + ...) +{ + DECARTA_LOGD ("xml_reader_open"); + if (!data){ + DECARTA_LOGW("data is NULL"); + return NULL; + } XmlReaderWrapper* reader = g_new0 (XmlReaderWrapper, 1); + char *xml_data = remove_noise (data); + if (0 == g_strcmp0(g_getenv (DECARTA_XML_LOG), "1")) printf ("\nresponse: %s", xml_data); + reader->doc = xmlParseDoc (BAD_CAST xml_data); + if (!reader->doc) { + DECARTA_LOGW("failed to xmlParseDoc(%s)", xml_data); + g_free (xml_data); + g_free (reader); + return NULL; + } + g_free (xml_data); + + reader->xpath_ctx = xmlXPathNewContext (reader->doc); + if (!reader->xpath_ctx) { + DECARTA_LOGW("failed to xmlXPathNewContext(0x%x)", reader->doc); + xmlFreeDoc (reader->doc); + g_free(reader); + return NULL; + } + + va_list ap; + char* ns= NULL; + char* ns_uri = NULL; + va_start(ap, data); + while( (ns = va_arg(ap, char*))!= NULL ){ + ns_uri= va_arg(ap, char*); + if (ns && ns_uri) + if (xmlXPathRegisterNs (reader->xpath_ctx, BAD_CAST ns, BAD_CAST ns_uri) < 0) { + DECARTA_LOGW ("failed to xmlXPathRegisterNs(0x%x, %s, %s)", reader->xpath_ctx, ns, ns_uri); + xmlFreeDoc (reader->doc); + xmlXPathFreeContext (reader->xpath_ctx); + g_free(reader); + reader = NULL; + break; + } + } + va_end(ap); + + return reader; +} + +void +xml_reader_close (XmlReaderHandler handle) +{ + XmlReaderWrapper* reader = (XmlReaderWrapper*)handle; + if (!reader) { + DECARTA_LOGW("handle is NULL"); + return; + } + if(reader->doc) xmlFreeDoc (reader->doc); + if(reader->xpath_ctx) xmlXPathFreeContext (reader->xpath_ctx); + g_free(reader); +} + +gboolean +xml_reader_is_valid (XmlReaderHandler handle, + const char *xpath_format, + ...) +{ + XmlReaderWrapper* reader = (XmlReaderWrapper*)handle; + if (!handle || !reader->xpath_ctx || !xpath_format) { + DECARTA_LOGW("handle or xmlXPathContextPtr or xpath_format is NULL"); + return FALSE; + } + gboolean ret = TRUE; + va_list ap; + va_start(ap, xpath_format); + char *xpath = g_strdup_vprintf (xpath_format, ap); + va_end(ap); + xmlXPathObjectPtr obj = xmlXPathEvalExpression (BAD_CAST xpath, reader->xpath_ctx); + g_free (xpath); + if (!obj) ret = FALSE; + else if (!obj->nodesetval || xmlXPathNodeSetIsEmpty (obj->nodesetval)) ret = FALSE; + xmlXPathFreeObject (obj); + return ret; +} + +gboolean +xml_reader_get_string (XmlReaderHandler handle, + char **string, + const char *xpath_format, + ...) +{ + XmlReaderWrapper* reader = (XmlReaderWrapper*)handle; + if (!reader || !reader->xpath_ctx || !xpath_format || !string) { + DECARTA_LOGW("handle or xmlXPathContextPtr or xpath_format or string is NULL"); + return FALSE; + } + + + va_list ap; + va_start(ap, xpath_format); + char *xpath = g_strdup_vprintf (xpath_format, ap); + va_end(ap); + gboolean ret = FALSE; + xmlXPathObjectPtr obj = xmlXPathEvalExpression (BAD_CAST xpath, reader->xpath_ctx); + g_free(xpath); + if (obj) { + if (obj->nodesetval && !xmlXPathNodeSetIsEmpty (obj->nodesetval)) { + *string = (char*)xmlXPathCastNodeSetToString (obj->nodesetval); + ret = TRUE; + } else ret = FALSE; + xmlXPathFreeObject (obj); + } + return ret; +} + +/** + * __sax_internal_subset_cb: + * @ctxt: An XML parser context + * + * Does this document has an internal subset + */ +static void +__sax_internal_subset_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, + const xmlChar *ExternalID, const xmlChar *SystemID) +{ + + if (!name) { + DECARTA_LOGD("[ERROR] name is NULL\n"); + return; + } + + DECARTA_LOGD( "SAX.internalSubset(%s,", name); + if (ExternalID == NULL) { + DECARTA_LOGD( " ,"); + } else { + DECARTA_LOGD( " %s,", ExternalID); + } + if (SystemID == NULL) { + DECARTA_LOGD( " )\n"); + } else { + DECARTA_LOGD( " %s)\n", SystemID); + } +} + +/** + * __sax_is_standalone_cb: + * @ctxt: An XML parser context + * + * Is this document tagged standalone ? + * + * Returns 1 if true + */ +static int +__sax_is_standalone_cb(void *ctx ATTRIBUTE_UNUSED) +{ + + DECARTA_LOGD( "SAX.isStandalone()\n"); + return(0); +} + +/** + * __sax_has_internal_subset_cb: + * @ctxt: An XML parser context + * + * Does this document has an internal subset + * + * Returns 1 if true + */ +static int +__sax_has_internal_subset_cb(void *ctx ATTRIBUTE_UNUSED) +{ + + DECARTA_LOGD( "SAX.hasInternalSubset()\n"); + return(0); +} + +/** + * __sax_has_external_subset_cb: + * @ctxt: An XML parser context + * + * Does this document has an external subset + * + * Returns 1 if true + */ +static int +__sax_has_external_subset_cb(void *ctx ATTRIBUTE_UNUSED) +{ + + DECARTA_LOGD( "SAX.hasExternalSubset()\n"); + return(0); +} + +/** + * __sax_resolve_entity_cb: + * @ctxt: An XML parser context + * @publicId: The public ID of the entity + * @systemId: The system ID of the entity + * + * Special entity resolver, better left to the parser, it has + * more context than the application layer. + * The default behaviour is to NOT resolve the entities, in that case + * the ENTITY_REF nodes are built in the structure (and the parameter + * values). + * + * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour. + */ +static xmlParserInputPtr +__sax_resolve_entity_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId) +{ + + DECARTA_LOGD( "SAX.resolveEntity("); + if (publicId != NULL) { + DECARTA_LOGD( "%s", (char *)publicId); + } else { + DECARTA_LOGD( " "); + } + if (systemId != NULL) { + DECARTA_LOGD( ", %s)\n", (char *)systemId); + } else { + DECARTA_LOGD( ", )\n"); + } + + return(NULL); +} + +/** + * __sax_get_entity_cb: + * @ctxt: An XML parser context + * @name: The entity name + * + * Get an entity by name + * + * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour. + */ +static xmlEntityPtr +__sax_get_entity_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name) +{ + if (!name) { + DECARTA_LOGD("[ERROR] name is NULL\n"); + return; + } + DECARTA_LOGD( "SAX.getEntity(%s)\n", name); + return(NULL); +} + +/** + * __sax_entity_decl_cb: + * @ctxt: An XML parser context + * @name: the entity name + * @type: the entity type + * @publicId: The public ID of the entity + * @systemId: The system ID of the entity + * @content: the entity value (without processing). + * + * An entity definition has been parsed + */ +static void +__sax_entity_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type, + const xmlChar *publicId, const xmlChar *systemId, xmlChar *content) +{ + if (!name || !type) { + DECARTA_LOGD("[ERROR] name or type is NULL\n"); + return; + } + const xmlChar *nullstr = BAD_CAST "(null)"; + /* not all libraries handle printing null pointers nicely */ + if (publicId == NULL) { + publicId = nullstr; + } + if (systemId == NULL) { + systemId = nullstr; + } + if (content == NULL) { + content = (xmlChar *)nullstr; + } + + DECARTA_LOGD( "SAX.entityDecl(%s, %d, %s, %s, %s)\n", + name, type, publicId, systemId, content); +} + +/** + * __sax_notation_decl_cb: + * @ctxt: An XML parser context + * @name: The name of the notation + * @publicId: The public ID of the entity + * @systemId: The system ID of the entity + * + * What to do when a notation declaration has been parsed. + */ +static void +__sax_notation_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, + const xmlChar *publicId, const xmlChar *systemId) +{ + + if (!name || !publicId || !systemId) { + DECARTA_LOGD("[ERROR] name or publicId or systemId is NULL\n"); + return; + } + DECARTA_LOGD( "SAX.notationDecl(%s, %s, %s)\n", + (char *) name, (char *) publicId, (char *) systemId); +} + +/** + * __sax_attribute_decl_cb: + * @ctxt: An XML parser context + * @name: the attribute name + * @type: the attribute type + * + * An attribute definition has been parsed + */ +static void +__sax_attribute_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem, + const xmlChar * name, int type, int def, + const xmlChar * defaultValue, xmlEnumerationPtr tree) +{ + if (!elem || !name || !type || !def) { + DECARTA_LOGD("[ERROR] elem or name or type or def is NULL\n"); + return; + } + if (defaultValue == NULL) { + DECARTA_LOGD( "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n", + elem, name, type, def); + } else { + DECARTA_LOGD( "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n", + elem, name, type, def, defaultValue); + } + xmlFreeEnumeration(tree); +} + +/** + * __sax_element_decl_cb: + * @ctxt: An XML parser context + * @name: the element name + * @type: the element type + * @content: the element value (without processing). + * + * An element definition has been parsed + */ +static void +__sax_element_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type, + xmlElementContentPtr content ATTRIBUTE_UNUSED) +{ + if (!name || !type) { + DECARTA_LOGD("[ERROR] name or type is NULL\n"); + return; + } + + DECARTA_LOGD( "SAX.elementDecl(%s, %d, ...)\n", name, type); +} + +/** + * __sax_unparsed_entity_decl_cb: + * @ctxt: An XML parser context + * @name: The name of the entity + * @publicId: The public ID of the entity + * @systemId: The system ID of the entity + * @notationName: the name of the notation + * + * What to do when an unparsed entity declaration is parsed + */ +static void +__sax_unparsed_entity_decl_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, + const xmlChar *publicId, const xmlChar *systemId, + const xmlChar *notationName) +{ + if (!name) { + DECARTA_LOGD("[ERROR] name is NULL\n"); + return; + } + const xmlChar *nullstr = BAD_CAST "(null)"; + + if (publicId == NULL) { + publicId = nullstr; + } + if (systemId == NULL) { + systemId = nullstr; + } + if (notationName == NULL) { + notationName = nullstr; + } + + DECARTA_LOGD( "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n", + (char *) name, (char *) publicId, (char *) systemId, + (char *) notationName); +} + + +/** + * __sax_set_document_locator_cb: + * @ctxt: An XML parser context + * @loc: A SAX Locator + * + * Receive the document locator at startup, actually xmlDefaultSAXLocator + * Everything is available on the context, so this is useless in our case. + */ +static void +__sax_set_document_locator_cb(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED) +{ + DECARTA_LOGD( "SAX.setDocumentLocator()\n"); +} + +/** + * __sax_start_document_cb: + * @ctxt: An XML parser context + * + * called when the document start being processed. + */ +static void +__sax_start_document_cb(void *ctx) +{ + DECARTA_LOGD( "SAX.startDocument()\n"); + if (!ctx) { + DECARTA_LOGD("[ERROR] ctx is NULL\n"); + return; + } + + sax_route_data_s *route_data = (sax_route_data_s *)ctx; + + /** error check */ + route_data->has_error = 0; + route_data->error_code_str = NULL; + route_data->error_message_str = NULL; + route_data->error_severity_str = NULL; + + /** check wether has route responce */ + route_data->has_route_resp = 0; + + route_data->route_geometry_state = 0; + route_data->route_totaltime_state = 0; + route_data->route_totaldist_state = 0; + route_data->route_bbox_state = 0; + + route_data->route_start_state = 0; + route_data->route_end_state = 0; + + route_data->route_map_overview_state = 0; + + route_data->route_instruction_state = 0; + route_data->route_map_state = 0; + +} + +/** + * __sax_end_document_cb: + * @ctxt: An XML parser context + * + * called when the document end has been detected. + */ +static void +__sax_end_document_cb(void *ctx ATTRIBUTE_UNUSED) +{ + DECARTA_LOGD( "SAX.endDocument()\n"); + +} + + +/** + * __sax_reference_cb: + * @ctxt: An XML parser context + * @name: The entity name + * + * called when an entity reference is detected. + */ +static void +__sax_reference_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name) +{ + if (!name) { + DECARTA_LOGD("[ERROR] name is NULL\n"); + return; + } + DECARTA_LOGD( "SAX.reference(%s)\n", name); +} + +/** + * __sax_characters_cb: + * @ctxt: An XML parser context + * @ch: a xmlChar string + * @len: the number of xmlChar + * + * receiving some chars from the parser. + * Question: how much at a time ??? + */ +static void +__sax_characters_cb(void *ctx, const xmlChar *ch, int len) +{ + if (!ctx || !ch) { + DECARTA_LOGD("[ERROR] ctx or ch is NULL\n"); + return; + } + + sax_route_data_s *route_data = (sax_route_data_s *)ctx; + + if (route_data->route_geometry_state) { + DECARTA_LOGD("save the VectorString string\n"); + route_data->route_geometry_str = g_strndup((gchar *) ch, len); + } else if (route_data->route_totaltime_state) { + DECARTA_LOGD("save the totaltime string\n"); + route_data->route_totaltime_str = g_strndup((gchar *) ch, len); + } else if (route_data->route_totaldist_state) { + /** get string from attribute */ + DECARTA_LOGD("save the totaldistance string\n"); + } else if (route_data->route_bbox_state == 2) { + DECARTA_LOGD("save the route bbox pos1 string\n"); + /** get bbox pos1 */ + route_data->route_bbox_pos1_str = g_strndup((gchar *) ch, len); + } else if (route_data->route_bbox_state == 4) { + DECARTA_LOGD("save the route bbox pos2 string\n"); + /** get bbox pos2 */ + route_data->route_bbox_pos2_str = g_strndup((gchar *) ch, len); + } else if (route_data->route_start_state == 3) { + /** start address pos */ + DECARTA_LOGD("save the route start address pos string\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->pos = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start pos [%s]\n", route_start_addr_item->pos); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_start_state == 5) { + /** start address freeform address */ + DECARTA_LOGD("save the route start address freeform address string\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->freeform_addr = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start freeform address [%s]\n", route_start_addr_item->freeform_addr); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_start_state == 8) { + /** start address form address's street */ + DECARTA_LOGD("save the route start address form address's street\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->street = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start street [%s]\n", route_start_addr_item->street); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_start_state == 9) { + /** start address form address's CountrySubdivision */ + DECARTA_LOGD("save the route start address form address's CountrySubdivision\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->country_subdivision = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start country_subdivision [%s]\n", route_start_addr_item->country_subdivision); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_start_state == 10) { + /** start address form address's CountrySecondarySubdivision */ + DECARTA_LOGD("save the route CountrySecondarySubdivision\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->country_2_subdivision = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start country_2_subdivision [%s]\n", route_start_addr_item->country_2_subdivision); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_start_state == 11) { + /** start address form address's Municipality */ + DECARTA_LOGD("save the route form address's Municipality\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->municipality = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start municipality [%s]\n", route_start_addr_item->municipality); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_start_state == 12) { + /** start address form address's MunicipalitySubdivision */ + DECARTA_LOGD("save the route form address's MunicipalitySubdivision string\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->municipality_subdivision = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start municipality_subdivision [%s]\n", route_start_addr_item->municipality_subdivision); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_start_state == 13) { + /** start address form address's PostalCode */ + DECARTA_LOGD("save the route PostalCode string\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->postcode = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start postcode [%s]\n", route_start_addr_item->postcode); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_start_state == 14) { + /** start address form address's landmark name */ + DECARTA_LOGD("save the route landmark string\n"); + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->landmark_name = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb start landmark_name [%s]\n", route_start_addr_item->landmark_name); + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_start_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 3) { + /** end address pos */ + DECARTA_LOGD("save the route end address pos string\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->pos = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end pos [%s]\n", route_end_addr_item->pos); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 5) { + /** end address freeform address */ + DECARTA_LOGD("save the route end address freeform address string\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->freeform_addr = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end freeform address [%s]\n", route_end_addr_item->freeform_addr); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 8) { + /** end address form address's street */ + DECARTA_LOGD("save the route end address form address's street\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->street = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end street [%s]\n", route_end_addr_item->street); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 9) { + /** end address form address's CountrySubdivision */ + DECARTA_LOGD("save the route end address form address's CountrySubdivision\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->country_subdivision = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end country_subdivision [%s]\n", route_end_addr_item->country_subdivision); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 10) { + /** end address form address's CountrySecondarySubdivision */ + DECARTA_LOGD("save the route end CountrySecondarySubdivision\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->country_2_subdivision = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end country_2_subdivision [%s]\n", route_end_addr_item->country_2_subdivision); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 11) { + /** end address form address's Municipality */ + DECARTA_LOGD("save the route end form address's Municipality\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->municipality = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end municipality [%s]\n", route_end_addr_item->municipality); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 12) { + /** end address form address's MunicipalitySubdivision */ + DECARTA_LOGD("save the route form end address's MunicipalitySubdivision string\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->municipality_subdivision = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end municipality_subdivision [%s]\n", route_end_addr_item->municipality_subdivision); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 13) { + /** end address form address's PostalCode */ + DECARTA_LOGD("save the route end PostalCode string\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->postcode = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end postcode [%s]\n", route_end_addr_item->postcode); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 14) { + /** end address form address's landmark name */ + DECARTA_LOGD("save the route end landmark string\n"); + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->landmark_name = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb end landmark_name [%s]\n", route_end_addr_item->landmark_name); + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_end_addr_list g_list_last NULL\n"); + } + } else if (route_data->route_map_overview_state == 3) { + /** overview URL */ + DECARTA_LOGD("save the route overview URL string\n"); + route_data->route_ov_tile_url_str = g_strndup((gchar *) ch, len); + } else if (route_data->route_map_overview_state == 5) { + /** overview pos1 */ + DECARTA_LOGD("save the route overview pos1 string\n"); + route_data->route_ov_pos1_str = g_strndup((const gchar *) ch, len); + } else if (route_data->route_map_overview_state == 7) { + /** overview pos2 */ + DECARTA_LOGD("save the route overview pos2 string\n"); + route_data->route_ov_pos2_str = g_strndup((gchar *) ch, len); + } else if (route_data->route_instruction_state == 3) { + /** instruction string */ + DECARTA_LOGD("save the route instruction string\n"); + GList *last_item = g_list_last(route_data->route_inst_str_list); + if (last_item) { + decarta_route_inst_str_s *route_inst_item = (decarta_route_inst_str_s *)last_item->data; + if (route_inst_item) { + route_inst_item->instruction = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb instruction [%s]\n", route_inst_item->instruction); + } else { + DECARTA_LOGD("[ERROR] characters cb route_inst_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_inst_str_list g_list_last NULL\n"); + } + } else if (route_data->route_map_state == 3) { + /** map URL */ + DECARTA_LOGD("save the route map URL string\n"); + /** Notice: the map URL seprated to pieces */ + GList *last_item = g_list_last(route_data->route_map_str_list); + if (last_item) { + decarta_route_map_str_s *route_map_item = (decarta_route_map_str_s *)last_item->data; + if (route_map_item) { + if (route_map_item->url == NULL) { + route_map_item->url = g_strndup((gchar *) ch, len); + } else { + char *former_url = g_strdup(route_map_item->url); + g_free(route_map_item->url); + char *cur_url = g_strndup((gchar *) ch, len); + route_map_item->url = g_strdup_printf("%s%s", former_url, cur_url); + g_free(former_url); + g_free(cur_url); + } + DECARTA_LOGD("characters cb URL [%s]\n", route_map_item->url); + } else { + DECARTA_LOGD("[ERROR] characters cb route_map_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_map_str_list g_list_last NULL\n"); + } + } else if (route_data->route_map_state == 5) { + /** map pos1 */ + DECARTA_LOGD("save the route map pos1 string\n"); + GList *last_item = g_list_last(route_data->route_map_str_list); + if (last_item) { + decarta_route_map_str_s *route_map_item = (decarta_route_map_str_s *)last_item->data; + if (route_map_item) { + route_map_item->pos1 = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb pos1 [%s]\n", route_map_item->pos1); + } else { + DECARTA_LOGD("[ERROR] characters cb route_map_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_map_str_list g_list_last NULL\n"); + } + } else if (route_data->route_map_state == 7) { + /** map pos2 */ + DECARTA_LOGD("save the route map pos2 string\n"); + GList *last_item = g_list_last(route_data->route_map_str_list); + if (last_item) { + decarta_route_map_str_s *route_map_item = (decarta_route_map_str_s *)last_item->data; + if (route_map_item) { + route_map_item->pos2 = g_strndup((gchar *) ch, len); + DECARTA_LOGD("characters cb pos2 [%s]\n", route_map_item->pos2); + } else { + DECARTA_LOGD("[ERROR] characters cb route_map_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] characters cb route_map_str_list g_list_last NULL\n"); + } + } else { + DECARTA_LOGD("Not save string in character callback\n"); + } +} + +/** + * __sax_ignorable_whitespace_cb: + * @ctxt: An XML parser context + * @ch: a xmlChar string + * @start: the first char in the string + * @len: the number of xmlChar + * + * receiving some ignorable whitespaces from the parser. + * Question: how much at a time ??? + */ +static void +__sax_ignorable_whitespace_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len) +{ + if (!ch) { + DECARTA_LOGD("[ERROR] ch is NULL\n"); + return; + } + + char output[40]; + int i; + + for (i = 0;(ihas_error = 1; + /** */ + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("severity", (char *) attributes[i])) { + route_data->error_severity_str = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("severity: [%s]", route_data->error_severity_str); + } else if (attributes[i] && !g_strcmp0("message", (char *) attributes[i])) { + route_data->error_message_str = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("message: [%s]\n", route_data->error_message_str); + } else if (attributes[i] && !g_strcmp0("errorCode", (char *) attributes[i])) { + route_data->error_code_str = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("errorCode: [%s]\n", route_data->error_code_str); + } + } + } + } else if (!g_strcmp0("DetermineRouteResponse", (char *) localname)) { + route_data->has_route_resp = 1; + } else if (!g_strcmp0("VectorString", (char *) localname)) { + DECARTA_LOGD("enter the VectorString state"); + route_data->route_geometry_state = 1; + } else if (!g_strcmp0("TotalTime", (char *) localname)) { + route_data->route_totaltime_state = 1; + } else if (!g_strcmp0("TotalDistance", (char *) localname)) { + route_data->route_totaldist_state = 1; + /** total distance is attribute: value='1796...' */ + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("value", (char *) attributes[i])) { + route_data->route_totaldist_str = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("TotalDistance: %s\n", route_data->route_totaldist_str); + } + } + } + } else if (!g_strcmp0("BoundingBox", (char *) localname)) { + route_data->route_bbox_state = 1; + } else if (!g_strcmp0("StartAddressCandidates", (char *) localname)) { + route_data->route_start_state = 1; + } else if (!g_strcmp0("EndAddressCandidates", (char *) localname)) { + route_data->route_end_state = 1; + } else if (!g_strcmp0("GeocodedAddress", (char *) localname)) { + if (route_data->route_start_state == 1) { + route_data->route_start_state = 2; + /** create one geocoded address item, and append to list */ + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)g_new0(decarta_geo_addr_s, 1); + route_start_addr_item->is_freeform = 0; + route_data->route_start_addr_list = g_list_append (route_data->route_start_addr_list, (gpointer)route_start_addr_item); + } else if (route_data->route_end_state == 1) { + route_data->route_end_state = 2; + /** create one geocoded address item, and append to list */ + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)g_new0(decarta_geo_addr_s, 1); + route_end_addr_item->is_freeform = 0; + route_data->route_end_addr_list = g_list_append (route_data->route_end_addr_list, (gpointer)route_end_addr_item); + } + } else if (!g_strcmp0("Point", (char *) localname)) { + /** plz ignore element, maybe not exist */ + } else if (!g_strcmp0("pos", (char *) localname)) { + if (route_data->route_bbox_state == 1) { + route_data->route_bbox_state = 2; + } else if (route_data->route_bbox_state == 3) { + route_data->route_bbox_state = 4; + } else if (route_data->route_map_overview_state == 4) { + /** overview pos1 */ + route_data->route_map_overview_state = 5; + } else if (route_data->route_map_overview_state == 6) { + /** overview pos2 */ + route_data->route_map_overview_state = 7; + } else if (route_data->route_map_state == 4) { + /** map pos1 */ + route_data->route_map_state = 5; + } else if (route_data->route_map_state == 6) { + /** map pos2 */ + route_data->route_map_state = 7; + } else if (route_data->route_start_state == 2) { + route_data->route_start_state = 3; + } else if (route_data->route_end_state == 2) { + route_data->route_end_state = 3; + } + } else if (!g_strcmp0("Address", (char *) localname)) { + if (route_data->route_start_state == 2) { + route_data->route_start_state = 4; + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("countryCode", (char *) attributes[i])) { + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->country_code = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("countryCode [%s]\n", route_start_addr_item->country_code); + } else { + DECARTA_LOGD("[ERROR] route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] g_list_last NULL\n"); + } + + } else if (attributes[i] && !g_strcmp0("language", (char *) attributes[i])) { + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->lang_code = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("lang_code [%s]\n", route_start_addr_item->lang_code); + } else { + DECARTA_LOGD("[ERROR] route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] g_list_last NULL\n"); + } + } + } + } + } else if (route_data->route_end_state == 2) { + route_data->route_end_state = 4; + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("countryCode", (char *) attributes[i])) { + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->country_code = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("countryCode [%s]\n", route_end_addr_item->country_code); + } else { + DECARTA_LOGD("[ERROR] route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] g_list_last NULL\n"); + } + + } else if (attributes[i] && !g_strcmp0("language", (char *) attributes[i])) { + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->lang_code = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("lang_code [%s]\n", route_end_addr_item->lang_code); + } else { + DECARTA_LOGD("[ERROR] route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] g_list_last NULL\n"); + } + + } + } + } + } + } else if (!g_strcmp0("freeFormAddress", (char *) localname)) { + if (route_data->route_start_state == 4) { + /** get free address, set free form address flag */ + route_data->route_start_state = 5; + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + route_start_addr_item->is_freeform = 1; + } else { + DECARTA_LOGD("[ERROR] g_list_last NULL\n"); + } + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 5; + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + route_end_addr_item->is_freeform = 1; + } else { + DECARTA_LOGD("[ERROR] g_list_last NULL\n"); + } + } + } else if (!g_strcmp0("StreetAddress", (char *) localname)) { + if (route_data->route_start_state == 4) { + route_data->route_start_state = 6; + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 6; + } + } else if (!g_strcmp0("Building", (char *) localname)) { + if (route_data->route_start_state == 6) { + route_data->route_start_state = 7; + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("number", (char *) attributes[i])) { + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_start_addr_item) { + route_start_addr_item->building_num = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("building_num [%s]\n", route_start_addr_item->building_num); + } else { + DECARTA_LOGD("[ERROR] route_start_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] g_list_last NULL\n"); + } + } + } + } + }else if (route_data->route_end_state == 6) { + route_data->route_end_state = 7; + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("number", (char *) attributes[i])) { + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + if (route_end_addr_item) { + route_end_addr_item->building_num = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("building_num [%s]\n", route_end_addr_item->building_num); + } else { + DECARTA_LOGD("[ERROR] route_end_addr_item NULL\n"); + } + } else { + DECARTA_LOGD("[ERROR] g_list_last NULL\n"); + } + } + } + } + } + } else if (!g_strcmp0("Street", (char *) localname)) { + if (route_data->route_start_state == 6) { + route_data->route_start_state = 8; + } else if (route_data->route_end_state == 6) { + route_data->route_end_state = 8; + + } + } else if (!g_strcmp0("Place", (char *) localname)) { + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("type", (char *) attributes[i])) { + char *type = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + if (!g_strcmp0("CountrySubDivision", type)) { + if (route_data->route_start_state == 4) { + route_data->route_start_state = 9; + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 9; + } + } else if (!g_strcmp0("CountrySecondarySubDivision", type)) { + if (route_data->route_start_state == 4) { + route_data->route_start_state = 10; + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 10; + } + } else if (!g_strcmp0("Municipality", type)) { + if (route_data->route_start_state == 4) { + route_data->route_start_state = 11; + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 11; + } + } else if (!g_strcmp0("MunicipalitySubdivision", type)) { + if (route_data->route_start_state == 4) { + route_data->route_start_state = 12; + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 12; + } + } else if (!g_strcmp0("Landmark", type)) { + if (route_data->route_start_state == 4) { + route_data->route_start_state = 14; + for (j = 0; j < nb_attributes * 5; j += 5) { + if (attributes[j] && !g_strcmp0("subType", (char *) attributes[j])) { + GList *last_item = g_list_last(route_data->route_start_addr_list); + if (last_item) { + decarta_geo_addr_s *route_start_addr_item = (decarta_geo_addr_s *)last_item->data; + route_start_addr_item->landmark_type = g_strndup((gchar *) attributes[j + 3], + (int)(attributes[j + 4] - attributes[j + 3])); + } + } + } + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 14; + for (j = 0; j < nb_attributes * 5; j += 5) { + if (attributes[j] && !g_strcmp0("subType", (char *) attributes[j])) { + GList *last_item = g_list_last(route_data->route_end_addr_list); + if (last_item) { + decarta_geo_addr_s *route_end_addr_item = (decarta_geo_addr_s *)last_item->data; + route_end_addr_item->landmark_type = g_strndup((gchar *) attributes[j + 3], + (int)(attributes[j + 4] - attributes[j + 3])); + } + } + } + } + } + g_free(type); + } + } + } + } else if (!g_strcmp0("PostalCode", (char *) localname)) { + if (route_data->route_start_state == 4) { + route_data->route_start_state = 13; + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 13; + } + } else if (!g_strcmp0("RouteMap", (char *) localname)) { + + decarta_route_map_str_s *route_map_item = (decarta_route_map_str_s *)g_new0(decarta_route_map_str_s, 1); + route_map_item->url = NULL; + route_data->route_map_str_list = g_list_append (route_data->route_map_str_list, (gpointer)route_map_item); + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("description", (char *) attributes[i])) { + route_map_item->description = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + if (!g_strcmp0("Route Overview", route_map_item->description)) { + DECARTA_LOGD("RouteMap: description=Route Overview\n"); + /** */ + route_data->route_map_overview_state = 1; + } else { + /** RouteMap */ + route_data->route_map_state = 1; + } + } + } + } + } else if (!g_strcmp0("Content", (char *) localname)) { + if (route_data->route_map_overview_state == 1) { + route_data->route_map_overview_state = 2; + } else if (route_data->route_map_state == 1) { + route_data->route_map_state = 2; + } + } else if (!g_strcmp0("URL", (char *) localname)) { + if (route_data->route_map_overview_state == 2) { + /** URL string */ + route_data->route_map_overview_state = 3; + } else if (route_data->route_map_state == 2) { + /** get URL string*/ + route_data->route_map_state = 3; + } + } else if (!g_strcmp0("BBoxContext", (char *) localname)) { + if (route_data->route_map_overview_state == 1) { + /** BBoxContext */ + route_data->route_map_overview_state = 4; + } else if (route_data->route_map_state == 1) { + /** BBoxContext */ + route_data->route_map_state = 4; + } + } else if (!g_strcmp0("RouteInstructionsList", (char *) localname)) { + route_data->route_instruction_state = 1; + } else if (!g_strcmp0("RouteInstruction", (char *) localname)) { + if (route_data->route_instruction_state == 1) { + /** RouteInstruction */ + route_data->route_instruction_state = 2; + decarta_route_inst_str_s *route_inst_item = (decarta_route_inst_str_s *)g_new0(decarta_route_inst_str_s, 1); + route_data->route_inst_str_list = g_list_append (route_data->route_inst_str_list, (gpointer)route_inst_item); + /** */ + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("description", (char *) attributes[i])) { + route_inst_item->description = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("description: %s\n", route_inst_item->description); + } else if (attributes[i] && !g_strcmp0("duration", (char *) attributes[i])) { + route_inst_item->duration = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("duration: %s\n", route_inst_item->duration); + } else if (attributes[i] && !g_strcmp0("tour", (char *) attributes[i])) { + route_inst_item->tour = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("tour: %s\n", route_inst_item->tour); + } + } + } + } + } else if (!g_strcmp0("Instruction", (char *) localname)) { + if (route_data->route_instruction_state == 2) { + /** get instruction string */ + route_data->route_instruction_state = 3; + } + } else if (!g_strcmp0("distance", (char *) localname)) { + if (route_data->route_instruction_state == 2) { + /** */ + route_data->route_instruction_state = 4; + GList *last_item = g_list_last(route_data->route_inst_str_list); + if (last_item) { + decarta_route_inst_str_s *route_inst_item = (decarta_route_inst_str_s *)last_item->data; + if (attributes != NULL) { + for (i = 0;i < nb_attributes * 5;i += 5) { + if (attributes[i] && !g_strcmp0("value", (char *) attributes[i])) { + if (route_inst_item) { + route_inst_item->distance = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("distance value: %s\n", route_inst_item->distance); + } else { + DECARTA_LOGD("[ERROR] startElement : route_inst_item NULL\n "); + char *distance = g_strndup((gchar *) attributes[i + 3], + (int)(attributes[i + 4] - attributes[i + 3])); + DECARTA_LOGD("distance value: %s\n", distance); + g_free(distance); + } + } + } + } + } else { + DECARTA_LOGD("[ERROR] startElement : g_list_last NULL\n "); + } + } + } else { + } +} + +/** + * __sax_end_element_ns_cb: + * @ctxt: An XML parser context + * @name: The element name + * + * called when the end of an element has been detected. + */ +static void +__sax_end_element_ns_cb(void *ctx, + const xmlChar *localname, + const xmlChar *prefix, + const xmlChar *URI) +{ + if (!ctx || !localname) { + DECARTA_LOGD("[ERROR] ctx or localname is NULL\n"); + return; + } + + DECARTA_LOGD( "SAX.endElementNs(%s)", (char *) localname); + + sax_route_data_s *route_data = (sax_route_data_s *)ctx; + if (!g_strcmp0("VectorString", (char *) localname)) { + DECARTA_LOGD("leave the VectorString state"); + route_data->route_geometry_state = 0; + } else if (!g_strcmp0("TotalTime", (char *) localname)) { + route_data->route_totaltime_state = 0; + } else if (!g_strcmp0("TotalDistance", (char *) localname)) { + route_data->route_totaldist_state = 0; + } else if (!g_strcmp0("BoundingBox", (char *) localname)) { + route_data->route_bbox_state = 0; + } else if (!g_strcmp0("pos", (char *) localname)) { + if (route_data->route_bbox_state == 2) { + route_data->route_bbox_state = 3; + } else if (route_data->route_bbox_state == 4) { + route_data->route_bbox_state = 1; + } else if (route_data->route_map_state == 5) { + /** map pos1 -> pos2 */ + route_data->route_map_state = 6; + } else if (route_data->route_map_state == 7) { + /** map pos2 -> BBoxContext */ + route_data->route_map_state = 4; + } else if (route_data->route_map_overview_state == 5) { + /** overview pos1 -> pos2 */ + route_data->route_map_overview_state = 6; + } else if (route_data->route_map_overview_state == 7) { + /** overview pos2 -> BBoxContext */ + route_data->route_map_overview_state = 4; + } else if (route_data->route_start_state == 3) { + route_data->route_start_state = 2; + } else if (route_data->route_end_state == 3) { + route_data->route_end_state = 2; + } + } else if (!g_strcmp0("StartAddressCandidates", (char *) localname)) { + route_data->route_start_state = 0; + } else if (!g_strcmp0("EndAddressCandidates", (char *) localname)) { + route_data->route_end_state = 0; + } else if (!g_strcmp0("GeocodedAddress", (char *) localname)) { + if (route_data->route_start_state == 2) { + route_data->route_start_state = 1; + } else if (route_data->route_end_state == 2) { + route_data->route_end_state = 1; + } + } else if (!g_strcmp0("Point", (char *) localname)) { + /** plz ignore this. */ + } else if (!g_strcmp0("Address", (char *) localname)) { + if (route_data->route_start_state == 4) { + route_data->route_start_state = 2; + } else if (route_data->route_end_state == 4) { + route_data->route_end_state = 2; + } + } else if (!g_strcmp0("freeFormAddress", (char *) localname)) { + if (route_data->route_start_state == 5) { + route_data->route_start_state = 4; + } else if (route_data->route_end_state == 5) { + route_data->route_end_state = 4; + } + } else if (!g_strcmp0("StreetAddress", (char *) localname)) { + if (route_data->route_start_state == 6) { + route_data->route_start_state = 4; + } else if (route_data->route_end_state == 6) { + route_data->route_end_state = 4; + } + } else if (!g_strcmp0("Building", (char *) localname)) { + if (route_data->route_start_state == 7) { + route_data->route_start_state = 6; + } else if (route_data->route_end_state == 7) { + route_data->route_end_state = 6; + } + } else if (!g_strcmp0("Street", (char *) localname)) { + if (route_data->route_start_state == 8) { + route_data->route_start_state = 6; + } else if (route_data->route_end_state == 8) { + route_data->route_end_state = 6; + } + } else if (!g_strcmp0("Place", (char *) localname)) { + if (route_data->route_start_state != 0) { + route_data->route_start_state = 4; + } else if (route_data->route_end_state != 0) { + route_data->route_end_state = 4; + } + } else if (!g_strcmp0("PostalCode", (char *) localname)) { + if (route_data->route_start_state == 13) { + route_data->route_start_state = 4; + } else if (route_data->route_end_state == 13) { + route_data->route_end_state = 4; + } + } else if (!g_strcmp0("RouteMap", (char *) localname)) { + if (route_data->route_map_overview_state == 1) { + route_data->route_map_overview_state = 0; + } else if (route_data->route_map_state == 1) { + route_data->route_map_state = 0; + } + } else if (!g_strcmp0("Content", (char *) localname)) { + if (route_data->route_map_overview_state == 2) { + route_data->route_map_overview_state = 1; + } else if (route_data->route_map_state == 2) { + /** Content -> RouteMap */ + route_data->route_map_state = 1; + } + } else if (!g_strcmp0("URL", (char *) localname)) { + if (route_data->route_map_overview_state == 3) { + route_data->route_map_overview_state = 2; + } else if (route_data->route_map_state == 3) { + /** URL -> Content */ + route_data->route_map_state = 2; + } + + } else if (!g_strcmp0("BBoxContext", (char *) localname)) { + if (route_data->route_map_overview_state == 4) { + route_data->route_map_overview_state = 1; + } else if (route_data->route_map_state == 4) { + /** BBoxContext -> RouteMap */ + route_data->route_map_state = 1; + } + + } else if (!g_strcmp0("RouteInstructionsList", (char *) localname)) { + route_data->route_instruction_state = 0; + } else if (!g_strcmp0("RouteInstruction", (char *) localname)) { + if (route_data->route_instruction_state == 2) { + /** "distance" -> next "RouteInstruction" */ + route_data->route_instruction_state = 1; + } + } else if (!g_strcmp0("Instruction", (char *) localname)) { + if (route_data->route_instruction_state == 3) { + route_data->route_instruction_state = 2; + } + } else if (!g_strcmp0("distance", (char *) localname)) { + if (route_data->route_instruction_state == 4) { + route_data->route_instruction_state = 2; + } + } else { + } +} + + +static xmlSAXHandler __sax2_handler_struct = { + __sax_internal_subset_cb, + __sax_is_standalone_cb, + __sax_has_internal_subset_cb, + __sax_has_external_subset_cb, + __sax_resolve_entity_cb, + __sax_get_entity_cb, + __sax_entity_decl_cb, + __sax_notation_decl_cb, + __sax_attribute_decl_cb, + __sax_element_decl_cb, + __sax_unparsed_entity_decl_cb, + __sax_set_document_locator_cb, + __sax_start_document_cb, + __sax_end_document_cb, + NULL, + NULL, + __sax_reference_cb, + __sax_characters_cb, + __sax_ignorable_whitespace_cb, + __sax_processing_instruction_cb, + __sax_comment_cb, + __sax_warning_cb, + __sax_error_cb, + __sax_fatal_error_cb, + __sax_get_parameter_entity_cb, + __sax_cdata_block_cb, + __sax_external_subset_cb, + XML_SAX2_MAGIC, + NULL, + __sax_start_element_ns_cb, + __sax_end_element_ns_cb, + NULL +}; + +static xmlSAXHandlerPtr __sax2_handler = &__sax2_handler_struct; + +int _xml_sax_read(const char* data, void *user_data) +{ + if (!data || !user_data) { + DECARTA_LOGD("[ERROR] data or user_data is NULL"); + return -1; + } + + int ret_val = -1; + char *xml_data = remove_noise(data); + if (xml_data) { + ret_val = xmlSAXUserParseMemory(__sax2_handler, user_data, (const char *)xml_data, strlen(xml_data)); + if (ret_val != 0) { + DECARTA_LOGD( "[ERROR] xmlSAXUserParseFile error [%d]", ret_val); + } + free(xml_data); + } + return ret_val; +} + diff --git a/decarta/xml_wrapper.h b/decarta/xml_wrapper.h new file mode 100755 index 0000000..44c74aa --- /dev/null +++ b/decarta/xml_wrapper.h @@ -0,0 +1,124 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef XML_WRAPPER_H_ +#define XML_WRAPPER_H_ + +#include + +G_BEGIN_DECLS + +typedef void* XmlWriterHandler; +typedef void* XmlReaderHandler; + +/** used for SAX parse route response */ +typedef struct{ + char *description; + char *duration; + char *tour; + char *instruction; + char *distance; +} decarta_route_inst_str_s; + +typedef struct{ + char *description; + char *url; + char *pos1; + char *pos2; +} decarta_route_map_str_s; + +typedef struct{ + char *pos; + char *country_code; + char *lang_code; + int is_freeform; + char *freeform_addr; + + char *building_num; + char *street; + char *country_subdivision; + char *country_2_subdivision; + char *municipality; + char *municipality_subdivision; + char *postcode; + char *landmark_type; + char *landmark_name; +} decarta_geo_addr_s; + + +typedef struct { + + /** error */ + int has_error; + char *error_code_str; + char *error_message_str; + char *error_severity_str; + + /** route*/ + int has_route_resp; + + int route_geometry_state; + char *route_geometry_str; + + int route_totaltime_state; + char *route_totaltime_str; + + int route_totaldist_state; + char *route_totaldist_str; + + int route_bbox_state; + char *route_bbox_pos1_str; + char *route_bbox_pos2_str; + + int route_start_state; + GList *route_start_addr_list; + int route_end_state; + GList *route_end_addr_list; + + int route_map_overview_state; + char *route_ov_tile_url_str; + char *route_ov_pos1_str; + char *route_ov_pos2_str; + + int route_instruction_state; + GList *route_inst_str_list; + + int route_map_state; + GList *route_map_str_list; +} sax_route_data_s; + +XmlWriterHandler xml_writer_open(char* encoding); +gboolean xml_writer_close (XmlWriterHandler handle, char **content, unsigned int *size); +gboolean xml_writer_all_start (XmlWriterHandler handle, const char* element, const char* content, ...); +gboolean xml_writer_element_start (XmlWriterHandler handle, const char* element); +gboolean xml_writer_attribute_write (XmlWriterHandler handle, const gchar *name, const gchar *value); +gboolean xml_writer_end (XmlWriterHandler handle); + +XmlReaderHandler xml_reader_open (const char* data, ...); +void xml_reader_close (XmlReaderHandler handle); +gboolean xml_reader_is_valid (XmlReaderHandler handle, const char *xpath_format, ...); +gboolean xml_reader_get_string (XmlReaderHandler handle, char **string, const char *xpath_format, ...); +int _xml_sax_read(const char* data, void *user_data); + + +G_END_DECLS + +#endif diff --git a/elm_module/Makefile.am b/elm_module/Makefile.am new file mode 100644 index 0000000..d402a87 --- /dev/null +++ b/elm_module/Makefile.am @@ -0,0 +1,19 @@ +dir_decarta = $(top_srcdir)/decarta + +pkgdir = $(libdir)/elementary/modules/decarta-normal/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la + +module_la_SOURCES = \ + decarta.c + +module_la_CFLAGS = \ + -fPIC \ + -I$(dir_decarta)\ + $(ELM_MOD_CFLAGS) + +module_la_LDFLAGS =\ + -no-undefined -module -avoid-version +module_la_LIBADD =\ + $(dir_decarta)/libdecarta.la\ + $(ELM_MOD_LIBS) \ + -lm diff --git a/elm_module/decarta.c b/elm_module/decarta.c new file mode 100755 index 0000000..4aface8 --- /dev/null +++ b/elm_module/decarta.c @@ -0,0 +1,379 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#include +#include + +#include "decarta.h" + +#define ZOOM_MIN 0 +#define ZOOM_MAX 18 + +#ifdef M_PI + #undef M_PI +#endif +#define M_PI 3.1415926535897932384626433832795 +#define DECARTA_URL_LENGTH 512 + +static Eina_Bool init = EINA_FALSE; +static Evas_Object *init_obj = NULL; +static char source_url[ZOOM_MAX+1][PATH_MAX]; +static int source_req_done[ZOOM_MAX+1]; +static Eina_Bool decarta_init = EINA_FALSE; + +typedef struct _Grid_Pos +{ + double lon; + double lat; +} Grid_Pos; + +static Eina_Bool url_fixed[ZOOM_MAX + 1] = {EINA_FALSE}; +static Grid_Pos map_center[ZOOM_MAX + 1] = +{ + {-180.000000,85.084059}, + {-90.000000,66.653476}, + {-135.000000,79.242052}, + {-174.375000,84.577645}, + {-168.750000,84.019227}, + {-174.375000,84.577645}, + {-177.187500,84.837041}, + {-178.593750,84.962060}, + {-179.296875,85.023432}, + {-179.648438,85.053838}, + {-179.824219,85.068972}, + {-179.912109,85.076521}, + {-179.956055,85.080292}, + {-179.978027,85.082176}, + {-179.989014,85.083117}, + {-179.994507,85.083588}, + {-179.997253,85.083824}, + {-179.998627,85.083941}, + {-179.999313,85.084000}}; +/* {-179.999657,85.084030}, + {-179.999828,85.084044}};*/ + +static Grid_Pos map_init[ZOOM_MAX+1] = +{ + {-180.000000,0.000000 }, + {-180.000000,66.653476}, + {-180.000000,79.242052}, + {-180.000000,82.724733}, + {-180.000000,84.019227}, + {-180.000000,84.577645}, + {-180.000000,84.837041}, + {-180.000000,84.962060}, + {-180.000000,85.023432}, + {-180.000000,85.053838}, + {-180.000000,85.068972}, + {-180.000000,85.076521}, + {-180.000000,85.080292}, + {-180.000000,85.082176}, + {-180.000000,85.083117}, + {-180.000000,85.083588}, + {-180.000000,85.083824}, + {-180.000000,85.083941}, + {-180.000000,85.084000}}; +/* {-180.000000,85.084030}, + {-180.000000,85.084044}};*/ + +static void map_callback(DecartaError error, const DecartaMap *map, void *data) +{ + int idx; + double lon, lat; + int zoom = (int)data; + + if ((error == DECARTA_ERROR_NONE) && (map) && (map->tile_url)) { + source_url[zoom][DECARTA_URL_LENGTH - 1] = '\0'; + url_fixed[zoom] = EINA_TRUE; + strncpy(source_url[zoom], map->tile_url, DECARTA_URL_LENGTH); + } + + if (strlen(source_url[zoom]) == 0 || error != DECARTA_ERROR_NONE) { + g_debug("map_callback() failed: zoom[%d], error[%d]", zoom, error); + source_req_done[zoom] = -1; + } else { + g_debug("map_callback() success: zoom[%d], error[%d]", zoom, error); + source_req_done[zoom] = 1; + } + + for (idx = ZOOM_MIN; idx <= ZOOM_MAX; idx++) { + if (source_req_done[idx] <= 0) { + break; + } + if (idx == ZOOM_MAX) { + init = EINA_TRUE; + } + } + + if ((init) && (init_obj)) { + init = EINA_FALSE; + elm_map_region_get(init_obj, &lon, &lat); + elm_map_region_bring_in(init_obj, lon - 0.00001, lat - 0.00001); + elm_map_region_show(init_obj, lon, lat); + } +} + +static void map_request(int zoom) +{ + strncpy(source_url[zoom], "", 1); + + int re = 0; + DecartaPosition *position = decarta_position_new (map_init[zoom].lat, map_init[zoom].lon); + re = decarta_search_map_async(position, zoom, &map_callback, (void*)zoom); + if (0 != re) { + g_debug("decarta_search_map_async failed!!!, re[%d]\n", re); + decarta_init = EINA_FALSE; + } else { + decarta_init = EINA_TRUE; + } + decarta_position_free(position); +} + +static double mercator_unproject(double t) +{ + return ((double)(M_PI) / 2.0) - 2.0 * atan(t); +} + +static double find_rad_phi(double phi, double t) +{ + double ecc = 0.08181919084262157; + double eSinPhi = ecc * sin(phi); + + double precalculate = t * pow(((1 - eSinPhi) / (1 + eSinPhi)), (ecc / 2)); + double result = (M_PI / 2) - (2 * (atan(precalculate))); + + return result; +} + +EAPI char *map_module_source_name_get(void) +{ + return strdup("Decarta Normal"); +} + +EAPI int map_module_tile_zoom_min_get(void) +{ + return 0; +} + +EAPI int map_module_tile_zoom_max_get(void) +{ + return 18; +} + +EAPI char *map_module_tile_url_get(Evas_Object *obj, int x, int y, int zoom) +{ + init_obj = obj; + + if (source_req_done[zoom] != 1) { + g_debug("source_req_done[%d] != 1 \n", zoom); + return strdup(""); + } + + if (strlen(source_url[zoom])) { + char *n, *nn, *e, *ee; + char strn[10], stre[10]; + char buf[PATH_MAX] = {'\0'}; + char buf2[PATH_MAX] = {'\0'}; + char _source_url[PATH_MAX] = {'\0'}; + + strn[0]=0; + stre[0]=0; + buf2[0]=0; + + strncpy(_source_url, source_url[zoom], PATH_MAX - 1); + n = strstr(_source_url, "&N="); + nn = strstr(n+1, "&"); + if (nn==NULL) { + nn = _source_url + strlen(_source_url); + } + + e = strstr(_source_url, "&E="); + ee = strstr(e+1, "&"); + if (ee==NULL) { + ee = _source_url + strlen(_source_url); + } + + strncat(strn, n + 3, nn - n - 3); + strncat(stre, e + 3, ee - e - 3); + + strncat(buf2, _source_url, n - _source_url); + snprintf(buf, PATH_MAX, "%s&N=%d&E=%d", buf2, atoi(strn) - y, atoi(stre) + x); + return strdup(buf); + } + + return strdup(""); +} + +EAPI double map_module_tile_scale_get(const Evas_Object *obj, double lon, double lat, int zoom) +{ + return 0; +} + +EAPI int map_module_route_source_get(void) +{ + return 0; +} + +EAPI char *map_module_route_url_get(const Evas_Object *obj, + const char *type_name, + int method, + double flon, + double flat, + double tlon, + double tlat) +{ + return strdup(""); +} + +EAPI char *map_module_name_url_get(Evas_Object *obj, int method, char *name, double lon, double lat) +{ + return strdup(""); +} + +EAPI Eina_Bool map_module_tile_geo_to_coord(const Evas_Object *obj, + int zoom, + double lon, + double lat, + int size, + int *x, + int *y) +{ + if (x) { + *x = floor((lon + 180.0) / 360.0 * size); + } + + double radLat = (lat * (2.0 * M_PI)) / 360.0; + double ecc = 0.08181919084262157; + + double sinPhi = sin(radLat); + double eSinPhi = ecc * sinPhi; + + double pw = pow((1.0 - eSinPhi) / (1.0 + eSinPhi), ecc); + double retVal = log(((1.0 + sinPhi) / (1.0 - sinPhi)) * pw) / 2.0; + + double y1 = retVal / (2 * M_PI / (double)size); + + double real_zoom = log2(size/256.0); + int floored_zoom = floor(real_zoom); + + if (floored_zoom >= ZOOM_MAX) { + lat = map_center[ZOOM_MAX].lat; + } else { + lat = map_center[floored_zoom].lat + (map_center[floored_zoom + 1].lat - map_center[floored_zoom].lat) * (real_zoom - floored_zoom); + } + + radLat = (lat * (2.0 * M_PI)) / 360.0; + ecc = 0.08181919084262157; + + sinPhi = sin(radLat); + eSinPhi = ecc * sinPhi; + + pw = pow((1.0 - eSinPhi) / (1.0 + eSinPhi), ecc); + retVal = log(((1.0 + sinPhi) / (1.0 - sinPhi)) * pw) / 2.0; + + double y2 = retVal / (2 * M_PI / (double)size); + + if (y) { + *y = floor(y2-y1) + 128; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool map_module_tile_coord_to_geo(const Evas_Object *obj, + int zoom, + int x, + int y, + int size, + double *lon, + double *lat) +{ + if (lon) { + *lon = x / (double)size * 360.0 - 180; + } + + if (lat) { + double real_zoom = log2(size/256.0); + int floored_zoom = floor(real_zoom); + double lat1; + + if (floored_zoom >= ZOOM_MAX) { + lat1 = map_center[ZOOM_MAX].lat; + } else { + lat1 = map_center[floored_zoom].lat + (map_center[floored_zoom + 1].lat - map_center[floored_zoom].lat) * (real_zoom - floored_zoom); + } + + double radLat = (lat1 * (2.0 * M_PI)) / 360.0; + double ecc = 0.08181919084262157; + + double sinPhi = sin(radLat); + double eSinPhi = ecc * sinPhi; + + double pw = pow((1.0 - eSinPhi) / (1.0 + eSinPhi), ecc); + double retVal = log(((1.0 + sinPhi) / (1.0 - sinPhi)) * pw) / 2.0; + + double yy = retVal / (2 * M_PI / (double)size); + + double phiEpsilon = 1E-7; + double phiMaxIter = 12.0; + + static double E = 2.718281828459045; + double t = pow(E, (-(floor(yy+128-y)) * (2 * M_PI / (double)size))); + + double prevPhi = mercator_unproject(t); + double newPhi = find_rad_phi(prevPhi, t); + + double iterCount = 0.0; + + while ((iterCount < phiMaxIter) && (fabs(prevPhi - newPhi) > phiEpsilon)) { + prevPhi = newPhi; + newPhi = find_rad_phi(prevPhi, t); + iterCount++; + } + *lat = newPhi * 180.0 / M_PI; + } + + return EINA_TRUE; +} + +static Eina_Bool _module_init(void) +{ + int z; + for (z = ZOOM_MIN; z <= ZOOM_MAX; z++){ + source_req_done[z] = 0; + map_request(z); + } + + return EINA_TRUE; +} + +static void _module_shutdown(void) +{ + if (decarta_init) { + decarta_search_map_async_cancel(); + } +} + +EINA_MODULE_INIT(_module_init); +EINA_MODULE_SHUTDOWN(_module_shutdown); + diff --git a/location_module/Makefile.am b/location_module/Makefile.am new file mode 100755 index 0000000..15c1146 --- /dev/null +++ b/location_module/Makefile.am @@ -0,0 +1,15 @@ +dir_decarta = $(top_srcdir)/decarta + +pkgdir = $(libdir)/location/module +pkg_LTLIBRARIES = libmap-service-decarta.la + +libmap_service_decarta_la_SOURCES = \ + location_decarta.c + +libmap_service_decarta_la_CFLAGS = \ + -fPIC\ + -I$(dir_decarta) \ + $(LOCATION_MOD_CFLAGS) +libmap_service_decarta_la_LIBADD = \ + $(dir_decarta)/libdecarta.la\ + $(LOCATION_MOD_LIBS) diff --git a/location_module/location_decarta.c b/location_module/location_decarta.c new file mode 100755 index 0000000..88f0316 --- /dev/null +++ b/location_module/location_decarta.c @@ -0,0 +1,1740 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "location_decarta.h" + +static char* service_name = "decarta"; +GSList * async_request_queue; + +int g_capa_list[] = { + TRUE, //MAP_SERVICE_PREF_LANGUAGE + TRUE, //MAP_SERVICE_PREF_DISTANCE_UNIT + + FALSE, //MAP_SERVICE_PREF_PROPERTY + + TRUE, //MAP_SERVICE_GEOCODE_TYPE + TRUE, //MAP_SERVICE_REVERSE_GEOCODE_TYPE + + TRUE, //MAP_SERVICE_POI_TYPE + TRUE, //MAP_SERVICE_POI_SEARCH_BY_ADDRESS + TRUE, //MAP_SERVICE_POI_SEARCH_BY_FREEFORM_ADDRESS + TRUE, //MAP_SERVICE_POI_SEARCH_BY_CIRCLE_BOUNDARY + FALSE, //MAP_SERVICE_POI_SEARCH_BY_RECT_BOUNDARY + FALSE, //MAP_SERVICE_POI_SEARCH_BY_POLYGON_BOUNDARY + TRUE, //MAP_SERVICE_POI_PREF_SORT_BY + TRUE, //MAP_SERVICE_POI_PREF_PROPERTY + TRUE, //MAP_SERVICE_POI_FILTER, + TRUE, //MAP_SERVICE_POI_FILTER_CATEGORY + + TRUE, //MAP_SERVICE_ROUTE_REQUEST_FREEFORM_ADDR_TO_AVOID + TRUE, //MAP_SERVICE_ROUTE_REQUEST_STRUCTED_ADDR_TO_AVOID + TRUE, //MAP_SERVICE_ROUTE_REQUEST_CIRCLE_AREA_TO_AVOID + FALSE, //MAP_SERVICE_ROUTE_REQUEST_RECT_AREA_TO_AVOID + FALSE, //MAP_SERVICE_ROUTE_REQUEST_POLYGON_AREA_TO_AVOID + TRUE, //MAP_SERVICE_ROUTE_REQUEST_FEATURE_TO_AVOID + TRUE, //MAP_SERVICE_ROUTE_PREF_TYPE + TRUE, //MAP_SERVICE_ROUTE_PREF_TRANSPORT_MODE + TRUE, //MAP_SERVICE_ROUTE_PREF_GEOMETRY_BOUNDING_BOX + TRUE, //MAP_SERVICE_ROUTE_PREF_GEOMETRY_RETRIEVAL + TRUE, //MAP_SERVICE_ROUTE_PREF_INSTRUCTION_GEOMETRY + TRUE, //MAP_SERVICE_ROUTE_PREF_INSTRUCTION_BOUNDING_BOX + TRUE, //MAP_SERVICE_ROUTE_PREF_INSTRUCTION_RETRIEVAL + TRUE, //MAP_SERVICE_ROUTE_PREF_REALTIME_TRAFFIC + FALSE, //MAP_SERVICE_ROUTE_PREF_PROPERTY + TRUE, //MAP_SERVICE_ROUTE_DISTANCE_UNIT + FALSE, //MAP_SERVICE_ROUTE_PROPERTY + FALSE, //MAP_SERVICE_ROUTE_SEGMENT_PROPERTY + FALSE //MAP_SERVICE_ROUTE_STEP_PROPERTY +}; + +static void +__pos_list_item_free(gpointer data) +{ + g_return_if_fail(data); + LocationPosition *position = (LocationPosition *)data; + location_position_free(position); +} + +static void +decarta_position_free_list(GList *position_list) +{ + g_return_if_fail(position_list); + g_list_free_full(position_list, (GDestroyNotify)__pos_list_item_free); +} + +static void +__acc_list_item_free(gpointer data) +{ + g_return_if_fail(data); + LocationAccuracy *accuracy = (LocationAccuracy *)data; + location_accuracy_free(accuracy); +} + +static void +decarta_accuracy_free_list(GList *accuracy_list) +{ + g_return_if_fail(accuracy_list); + g_list_free_full(accuracy_list, (GDestroyNotify)__acc_list_item_free); +} + +static int +convert_decarta_error_to_location_error (int err) +{ + switch (err) { + case DECARTA_ERROR_NONE: + return LOCATION_ERROR_NONE; + case DECARTA_ERROR_CONFIGURATION_FILE: + return LOCATION_ERROR_CONFIGURATION; + case DECARTA_ERROR_HTTP: + return LOCATION_ERROR_NETWORK_FAILED; + case DECARTA_ERROR_NOT_FOUND: + return LOCATION_ERROR_NOT_FOUND; + case DECARTA_ERROR_XML: + default: + return LOCATION_ERROR_UNKNOWN; + } +} + +static DecartaFormedAddress* +get_decarta_addr_from_location_addr (const LocationAddress *address) +{ + if (!address) return NULL; + return decarta_formed_address_new (address->building_number, + address->street, + address->state, NULL, + address->city, + address->district, + address->postal_code, NULL, NULL); +} + +static LocationAddress * +get_location_addr_from_decarta_addr (const DecartaAddress *deca_addr) +{ + if (!deca_addr) return NULL; + LocationAddress* addr = NULL; + if (deca_addr->is_freerorm) { + //FIXME: how to convert free to formed...?? + addr = location_address_new (NULL, NULL, NULL, NULL, NULL, NULL, NULL); + } else if (deca_addr->formed_addr) { + addr = location_address_new (deca_addr->formed_addr->street_number, + deca_addr->formed_addr->street_name, + deca_addr->formed_addr->district, + deca_addr->formed_addr->city, + deca_addr->formed_addr->state, + deca_addr->country_code, + deca_addr->formed_addr->postal_code); + } + return addr; +} + +static LocationPosition * +get_location_pos_from_decarta_pos (const DecartaPosition *deca_pos) +{ + if (!deca_pos) return NULL; + return location_position_new (0, deca_pos->latitude, deca_pos->longitude, 0, LOCATION_STATUS_2D_FIX); +} + +static LocationAccuracy * +get_location_acc_from_free_addr (const char *free_addr) +{ + if (!free_addr) return NULL; + //FIXME: how to convert free to formed...?? + return location_accuracy_new (LOCATION_ACCURACY_LEVEL_POSTALCODE, 0, 0); +} + +static LocationAccuracy * +get_location_acc_from_location_addr (const LocationAddress *addr) +{ + if (!addr) return NULL; + LocationAccuracy *accuracy = NULL; + + if (addr->building_number) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0); + else if (addr->street) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_STREET, 0, 0); + else if (addr->postal_code) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_POSTALCODE, 0, 0); + else if (addr->district || + addr->city) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_LOCALITY, 0, 0); + else if (addr->state) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_REGION, 0, 0); + else if (addr->country_code) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_COUNTRY, 0, 0); + else accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0); + + return accuracy; +} + +static LocationAccuracy * +get_location_acc_from_decarta_addr (const DecartaAddress *addr) +{ + if (!addr) return NULL; + LocationAccuracy *accuracy = NULL; + if (addr->is_freerorm && addr->freeform_address) { + //FIXME: how to convert free to formed...?? + accuracy = get_location_acc_from_free_addr(addr->freeform_address); + } else if (addr->formed_addr) { + DecartaFormedAddress *formed_addr = addr->formed_addr; + if (formed_addr->street_number) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0); + else if (formed_addr->street_number) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_STREET, 0, 0); + else if (formed_addr->postal_code) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_POSTALCODE, 0, 0); + else if (formed_addr->district || + formed_addr->city) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_LOCALITY, 0, 0); + else if (formed_addr->state) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_REGION, 0, 0); + else if (addr->country_code) accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_COUNTRY, 0, 0); + else accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0); + } + return accuracy; +} + + + +static void +get_lang (gchar country_code[3], gchar lang_code[3]) +{ + if (!country_code || !lang_code) return; + gchar* langset = vconf_get_str(VCONFKEY_LANGSET); + DECARTA_LOGD("getenv: %s", langset); + + if(langset == NULL){ + lang_code[0] = 'E'; + lang_code[1] = 'N'; + lang_code[2] = '\0'; + country_code[0] = 'U'; + country_code[1] = 'S'; + country_code[2] = '\0'; + }else{ + gchar* langset_upper = g_ascii_strup(langset, -1); + lang_code[0] = langset_upper[0]; + lang_code[1] = langset_upper[1]; + lang_code[2] = '\0'; + country_code[0] = langset_upper[3]; + country_code[1] = langset_upper[4]; + country_code[2] = '\0'; + g_free(langset_upper); + } + DECARTA_LOGD("Language: %s, Country: %s", lang_code, country_code); +} + +static int +get_service_name (gpointer handle, + gchar **_service_name) +{ + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(_service_name, LOCATION_ERROR_PARAMETER); + *_service_name = g_strdup(service_name); + return LOCATION_ERROR_NONE; +} + +static void +address_cb (DecartaError deca_err, + const DecartaGeocode *geocode, + void *userdata) +{ + LocationAddress *addr = NULL; + LocationAccuracy *acc = NULL; + LocationError error = LOCATION_ERROR_NONE; + DecartaData* data = (DecartaData*)userdata; + g_return_if_fail(data); + + async_request_queue = g_slist_remove(async_request_queue , data->handle); + + if (deca_err == DECARTA_ERROR_NONE && geocode && geocode->addr) { + DECARTA_LOGD("address_cb: success"); + addr = get_location_addr_from_decarta_addr (geocode->addr); + acc = get_location_acc_from_decarta_addr (geocode->addr); + } else { + DECARTA_LOGD("address_cb: failed"); + error = convert_decarta_error_to_location_error (deca_err); + } + if (data->addr_cb) data->addr_cb (error, addr, acc, data->userdata); + if (addr) location_address_free (addr); + if (acc) location_accuracy_free (acc); + g_free (data); +} + +static void +position_cb (DecartaError deca_err, + const GList *geocode_list, + void *userdata) +{ + LocationPosition *pos = NULL; + LocationAccuracy *acc = NULL; + GList *position_list = NULL; + GList *accuracy_list = NULL; + LocationError error = LOCATION_ERROR_NONE; + DecartaData* data = (DecartaData*)userdata; + g_return_if_fail(data); + + int i = 1; + + async_request_queue = g_slist_remove(async_request_queue , data->handle); + + if (deca_err == DECARTA_ERROR_NONE) { + DECARTA_LOGD("position_cb: success"); + + // get rid of const + GList *tmp_geocode_list = (GList *)geocode_list; + + const DecartaGeocode *geocode = NULL; + tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode); + + if (geocode) { + while (geocode) { + // Fixme: geocode->pos NULL case ? + pos = get_location_pos_from_decarta_pos (geocode->pos); + acc = location_accuracy_copy ((LocationAccuracy *)(data->userdata2)); + + DECARTA_LOGD("location decarta plugin: position_cb %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude); + + position_list = g_list_append (position_list, (gpointer)pos); + accuracy_list = g_list_append (accuracy_list, (gpointer)acc); + + if (!tmp_geocode_list) break; + tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode); + } + } else { + error = LOCATION_ERROR_NOT_FOUND; + } + } else { + DECARTA_LOGD("position_cb: failed"); + error = convert_decarta_error_to_location_error (deca_err); + } + if (data->pos_cb) { + data->pos_cb(error, position_list, accuracy_list, data->userdata); + } + + if(position_list) decarta_position_free_list(position_list); + if(accuracy_list) decarta_accuracy_free_list(accuracy_list); + + location_accuracy_free ((LocationAccuracy *)data->userdata2); + g_free (data); +} + +static void +__decarta_append_landmark_list (gpointer data, + gpointer user_data) +{ + DecartaPOI *poi = (DecartaPOI *)data; + GList **landmark_list = (GList **)user_data; + LocationPosition *loc_position = NULL; + LocationAddress *loc_address = NULL; + + LocationLandmark *landmark = location_landmark_new(); + + DECARTA_LOGD("name:%s id:%s phone_number:%s\n", poi->name, poi->id, poi->phone_number); + guint id_uint = g_ascii_strtoull(poi->id, NULL, 10); + location_landmark_set_id(landmark, id_uint); + location_landmark_set_name(landmark, poi->name); + location_landmark_set_phone_number(landmark, poi->phone_number); + + char *key = NULL; + char *value = NULL; + decarta_poi_info_table_iter_init (poi->info_list); + while (decarta_poi_info_list_table_next (poi->info_list, &key, &value)) + { + DECARTA_LOGD("%s=%s\n", key, value); + location_landmark_set_property(landmark, key, value); + } + if(poi->pos) { + DECARTA_LOGD("Position: %lf %lf\n", poi->pos->latitude, poi->pos->longitude); + loc_position = get_location_pos_from_decarta_pos (poi->pos); + location_landmark_set_position(landmark, loc_position); + } + if (poi->addr) { + loc_address = get_location_addr_from_decarta_addr (poi->addr); + location_landmark_set_address(landmark, loc_address); + } + + *landmark_list = g_list_append(*landmark_list, landmark); + +} + +static void +__decarta_free_landmark_list (gpointer data, + gpointer user_data) +{ + LocationLandmark* landmark = (LocationLandmark*)data; + location_landmark_free(landmark); +} + +static void +decarta_landmark_free_list(GList *landmark_list) +{ + g_return_if_fail(landmark_list); + g_list_foreach(landmark_list, (GFunc)__decarta_free_landmark_list, NULL); + g_list_free(landmark_list); + landmark_list = NULL; +} + + +static +void landmark_cb (DecartaError error, + const gchar *req_id_str, + const GList* poi_list, + const gchar *error_code, + const gchar *error_msg, + void *userdata) +{ + LocationError loc_error = LOCATION_ERROR_NONE; + DecartaData* data = (DecartaData*)userdata; + g_return_if_fail(data); + guint req_id = 0; + GList *landmark_list = NULL; + + if (error == DECARTA_ERROR_NONE) { + DECARTA_LOGD("landmark_cb: success, req_id %s", req_id_str); + + GList *tmp_poi_list = (GList *)poi_list; + g_list_foreach(tmp_poi_list, (GFunc)__decarta_append_landmark_list, &landmark_list); + } else { + DECARTA_LOGD("landmark_cb: failed, req_id %s, error code %s, msg %s", req_id_str, error_code, error_msg); + + loc_error = convert_decarta_error_to_location_error (error); + } + if (data->poi_cb) { + req_id = g_ascii_strtoull(req_id_str, NULL, 10); + gchar *code = g_strdup(error_code); + gchar *msg = g_strdup(error_msg); + data->poi_cb(loc_error, req_id, landmark_list, code, msg, data->userdata); + g_free(code); + g_free(msg); + } + if (landmark_list) decarta_landmark_free_list(landmark_list); + + g_free(data); +} + +// used to split the step into segments +static DecartaBoundary * +__decarta_route_boundary_new_for_rect (DecartaPosition* left_top, + DecartaPosition* right_bottom) +{ + g_return_val_if_fail(left_top, NULL); + g_return_val_if_fail(right_bottom, NULL); + + DecartaBoundary* boundary = g_slice_new0 (DecartaBoundary); + boundary->type = DECARTA_BOUNDARY_RECT; + boundary->rect.left_top = decarta_position_copy(left_top); + boundary->rect.right_bottom = decarta_position_copy(right_bottom); + return boundary; +} + +// postion's latitude & longitude between the boundary +static gboolean +__decarta_route_boundary_if_inside (DecartaBoundary* boundary, + const DecartaPosition* position) +{ + g_return_val_if_fail(boundary, FALSE); + g_return_val_if_fail(position, FALSE); + + gboolean is_inside = FALSE; + + switch(boundary->type) { + + case DECARTA_BOUNDARY_RECT: { + gdouble y = position->latitude; + gdouble x = position->longitude; + gdouble y_min, y_max; + gdouble x_min, x_max; + + if (boundary->rect.left_top->latitude < boundary->rect.right_bottom->latitude) { + y_min = boundary->rect.left_top->latitude; + y_max = boundary->rect.right_bottom->latitude; + } else { + y_max = boundary->rect.left_top->latitude; + y_min = boundary->rect.right_bottom->latitude; + } + + if (boundary->rect.left_top->longitude < boundary->rect.right_bottom->longitude) { + x_min = boundary->rect.left_top->longitude; + x_max = boundary->rect.right_bottom->longitude; + } else { + x_max = boundary->rect.left_top->longitude; + x_min = boundary->rect.right_bottom->longitude; + } + + if (x > x_min && x < x_max && y > y_min && y < y_max) { + DECARTA_LOGD("\tInside of Rectangular boundary"); + is_inside = TRUE; + } + + break; + } + case DECARTA_BOUNDARY_CIRCLE: { + DECARTA_LOGW("\tCircle boundary type is TBD."); + // TBD + break; + } + case DECARTA_BOUNDARY_POLYGON: { + DECARTA_LOGW("\tPolygon boundary type is TBD."); + // TBD + break; + } + default: { + DECARTA_LOGW("\tboundary type is undefined.[%d]", boundary->type); + break; + } + } + + return is_inside; +} + + +static void +__route_step_foreach_free (gpointer data) +{ + g_return_if_fail (data); + LocationRouteStep *step = (LocationRouteStep *) data; + location_route_step_free(step); +} + +static void +__route_segment_foreach_free (gpointer data) +{ + g_return_if_fail (data); + LocationRouteSegment *segment = (LocationRouteSegment *)data; + location_route_segment_free(segment); +} + +static LocationBoundary * +get_location_boundary_from_decarta_bbox(LocationPosition *pos1, + LocationPosition *pos2) +{ + g_return_val_if_fail(pos1, NULL); + g_return_val_if_fail(pos2, NULL); + LocationPosition *right_bottom = NULL; + LocationPosition *left_top = NULL; + + // determine the right_bottom & left_top postion + gdouble lon_interval = pos2->longitude - pos1->longitude; + if(lon_interval < 180 && lon_interval > -180) { + if(pos2->longitude <= pos1->longitude || pos2->latitude >= pos1->latitude) { + right_bottom = pos1; + left_top = pos2; + } else { + right_bottom = pos2; + left_top = pos1; + } + } + else { + if(pos2->longitude >= pos1->longitude || pos2->latitude >= pos1->latitude) { + right_bottom = pos1; + left_top = pos2; + } else { + right_bottom = pos2; + left_top = pos1; + } + } + + LocationBoundary *bbox = location_boundary_new_for_rect(left_top, right_bottom); + if (!bbox) { + g_printf("ERROR: get_location_boundary_from_decarta_bbox failed\n"); + return NULL; + } else { + return bbox; + } +} + +static GList * +get_location_route_list_from_decarta_route (const DecartaRoute *route, + const LocationPosition *origin, + const LocationPosition *destination) +{ + GList *route_list = NULL; + LocationRoute *loc_route = location_route_new(); + GList *seg_list = NULL; + GList *step_list = NULL; + + // set the route origin & destination + location_route_set_origin(loc_route, origin); + location_route_set_destination(loc_route, destination); + + // set the duration, distance + location_route_set_total_distance(loc_route, route->total_distance); + location_route_set_distance_unit(loc_route, "M"); + location_route_set_total_duration(loc_route, route->total_time); + + // set the rout rect area + LocationPosition *pos1 = get_location_pos_from_decarta_pos(route->box_corner1); + LocationPosition *pos2 = get_location_pos_from_decarta_pos(route->box_corner2); + // Fixme: can't create the boundary? + LocationBoundary *bbox = get_location_boundary_from_decarta_bbox(pos1, pos2); + location_position_free(pos1); + location_position_free(pos2); + location_route_set_bounding_box(loc_route, bbox); + + //set the segments for route + if (route->instructions_list) { + GList *inst_list = (GList *)route->instructions_list; + const DecartaRouteInstructions *inst = NULL; + inst_list = decarta_route_instructions_list_next( inst_list, &inst); + + GList *pos_list = (GList *)route->line_pos_list; + DecartaPosition *pos_prev = NULL; + // for each instruction + while (inst) { + LocationRouteSegment *seg = location_route_segment_new(); + location_route_segment_set_distance(seg, inst->distance); + location_route_segment_set_duration(seg, inst->duration); + + if (step_list) { + g_list_free_full (step_list, __route_step_foreach_free); + step_list = NULL; + } + + DecartaBoundary *instuct_rect = __decarta_route_boundary_new_for_rect(inst->map->box_corner1, inst->map->box_corner2); + + if (pos_list) { + const DecartaPosition *pos = NULL; + pos_list = decarta_position_list_next(pos_list, &pos); + while (pos) { + // search the whole pos list for each instruction + if (__decarta_route_boundary_if_inside(instuct_rect, pos)) { + LocationRouteStep *step = location_route_step_new(); + if (pos_prev) { + location_route_step_set_start_point(step, get_location_pos_from_decarta_pos(pos_prev)); + + // set geometry for location step + GList *geometry_list = NULL; + geometry_list = g_list_append(geometry_list, get_location_pos_from_decarta_pos(pos_prev)); + geometry_list = g_list_append(geometry_list, get_location_pos_from_decarta_pos(pos)); + location_route_step_set_geometry(step, geometry_list); + + decarta_position_free(pos_prev); + pos_prev = NULL; + } else { + // the first segment's first position should be Origin + location_route_step_set_start_point(step, origin); + } + location_route_step_set_instruction(step, inst->instruction); + location_route_step_set_end_point(step, get_location_pos_from_decarta_pos(pos)); + + step_list = g_list_append(step_list, step); + pos_prev = decarta_position_copy(pos); + } + + if (!pos_list) break; + pos_list = decarta_position_list_next(pos_list, &pos); + + } + + // search from beginning of the pos list + pos_list = (GList *)route->line_pos_list; + } + + if (step_list) { + location_route_segment_set_route_step(seg, step_list); + GList *seg_first = g_list_first(step_list); + if (seg_first) { + LocationRouteStep *seg_first_step = (LocationRouteStep *)seg_first->data; + const LocationPosition *seg_start_pos = location_route_step_get_start_point(seg_first_step); + location_route_segment_set_start_point(seg, seg_start_pos); + } + GList *seg_last = g_list_last(step_list); + if (seg_last) { + LocationRouteStep *seg_last_step = (LocationRouteStep *)seg_last->data; + const LocationPosition *seg_end_pos = location_route_step_get_end_point(seg_last_step); + location_route_segment_set_end_point(seg, seg_end_pos); + } + } + + seg_list = g_list_append(seg_list, seg); + + if (!inst_list) break; + inst_list = decarta_route_instructions_list_next (inst_list, &inst); + } + } + + if (seg_list) { + location_route_set_route_segment(loc_route, seg_list); + g_list_free_full (seg_list, __route_segment_foreach_free); + seg_list = NULL; + } + + route_list = g_list_append(route_list, loc_route); + return route_list; +} + + +static void +__decarta_free_route_list (gpointer data, + gpointer user_data) +{ + LocationRoute *route = (LocationRoute *)data; + GList *seg_list = (GList *)location_route_get_route_segment(route); + if (seg_list) { + g_list_foreach(seg_list, (GFunc)__route_segment_foreach_free, NULL); + } +} + +static void +decarta_route_free_list(GList *route_list) +{ + g_return_if_fail(route_list); + g_list_foreach(route_list, (GFunc)__decarta_free_route_list, NULL); + g_list_free(route_list); + route_list = NULL; +} + + +void route_callback(DecartaError error, + const gchar *req_id_str, + const DecartaRoute *route, + const gchar * error_code, + const gchar * error_msg, + void *user_data) +{ + LocationError loc_error = LOCATION_ERROR_NONE; + DecartaData* data = (DecartaData*)user_data; + g_return_if_fail(data); + guint req_id = 0; + GList *route_list = NULL; + LocationPosition *origin = (LocationPosition *)data->userdata2; + LocationPosition *destination = (LocationPosition *)data->userdata3; + + if (error == DECARTA_ERROR_NONE) { + DECARTA_LOGD("route_callback: success"); + route_list = get_location_route_list_from_decarta_route(route, origin, destination); + + } else { + DECARTA_LOGD("route_callback: failed"); + loc_error = convert_decarta_error_to_location_error (error); + } + if (data->route_cb) { + gchar *code = g_strdup(error_code); + gchar *msg = g_strdup(error_msg); + data->route_cb(loc_error, req_id, route_list, code, msg, data->userdata); + g_free(code); + g_free(msg); + } + if (route_list) decarta_route_free_list(route_list); + if (origin) location_position_free(origin); + if (destination) location_position_free(destination); + g_free(data); +} + +static int +get_geocode (gpointer handle, + const LocationAddress *addr, + const LocationMapPref *svc_pref, + GList **position_list, + GList **accuracy_list) +{ + DECARTA_LOGD("get_geocode"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (position_list, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (accuracy_list, LOCATION_ERROR_PARAMETER); + + int i = 1; + GList *geocode_list = NULL; + LocationPosition *pos = NULL; + LocationAccuracy *acc = NULL; + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + char *language_code = NULL; + char *country_code = NULL; + language_code = location_map_pref_get_language(svc_pref); + country_code = location_map_pref_get_country(svc_pref); + if (language_code == NULL || country_code == NULL) { + gchar tmp_country[3] = ""; + gchar tmp_language[3] = ""; + get_lang(tmp_country, tmp_language); + if (country_code == NULL) { + country_code = g_strdup(tmp_country); + } + if (language_code == NULL) { + language_code = g_strdup(tmp_language); + } + } + + DecartaFormedAddress *deca_formed_addr = get_decarta_addr_from_location_addr (addr); + DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, FALSE, NULL, deca_formed_addr); + decarta_formed_address_free (deca_formed_addr); + int ret = decarta_search_geocode(deca_addr, &geocode_list); + decarta_address_free (deca_addr); + + if (ret == DECARTA_ERROR_NONE) { + // libslp-location getting multi addresses. + /* can't change the geocode_list for del */ + GList *tmp_geocode_list = (GList *)geocode_list; + const DecartaGeocode *geocode = NULL; + tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode); + + while (geocode) { + pos = get_location_pos_from_decarta_pos (geocode->pos); + acc = get_location_acc_from_location_addr (addr); + + DECARTA_LOGD("location decarta plugin: get_geocode %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude); + + *position_list = g_list_append (*position_list, (gpointer)pos); + *accuracy_list = g_list_append (*accuracy_list, (gpointer)acc); + + if (!tmp_geocode_list) break; + tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode); + } + decarta_geocode_list_free (geocode_list); + } + return convert_decarta_error_to_location_error (ret); +} + +static gboolean +decarta_idle_geocode_cb (gpointer data) +{ + decarta_IdleData* idle_data = (decarta_IdleData*)data; + if (idle_data == NULL || idle_data->decarta_data == NULL) { + g_printf("idle_data or decarta_data is NULL\n"); + return FALSE; + } + + DecartaData *deca_data = (DecartaData *)idle_data->decarta_data; + int err = decarta_search_geocode_async(idle_data->addr, idle_data->geocode_cb, deca_data, &deca_data->handle); + async_request_queue = g_slist_prepend(async_request_queue , deca_data->handle); + if (DECARTA_ERROR_NONE != err) { + g_printf("Decarta Geocode Failed: %d\n", err); + + // call position_cb() to return the error code, and free DecartaData + if (idle_data->geocode_cb) { + idle_data->geocode_cb (err, NULL, idle_data->decarta_data); + } + } + decarta_address_free (idle_data->addr); + g_free(idle_data); + return FALSE; +} + + +static int +get_geocode_async (gpointer handle, + const LocationAddress * addr, + const LocationMapPref *svc_pref, + LocationPositionCB callback, + gpointer userdata) +{ + DECARTA_LOGD("get_geocode_async"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (callback, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + DecartaData* data = g_new0(DecartaData, 1); + + char *language_code = NULL; + char *country_code = NULL; + language_code = location_map_pref_get_language(svc_pref); + country_code = location_map_pref_get_country(svc_pref); + if (language_code == NULL || country_code == NULL) { + gchar tmp_country[3] = ""; + gchar tmp_language[3] = ""; + get_lang(tmp_country, tmp_language); + if (country_code == NULL) { + country_code = g_strdup(tmp_country); + } + if (language_code == NULL) { + language_code = g_strdup(tmp_language); + } + } + + DecartaFormedAddress *deca_formed_addr = get_decarta_addr_from_location_addr (addr); + DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, FALSE, NULL, deca_formed_addr); + decarta_formed_address_free (deca_formed_addr); + data->pos_cb = callback; + data->userdata = (gpointer)userdata; + data->userdata2 = (gpointer)get_location_acc_from_decarta_addr (deca_addr); + + // should call decarta_search_geocode_async in idle, OR request may be missed + decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1); + idle_data->addr = deca_addr; + idle_data->geocode_cb = position_cb; + idle_data->decarta_data = data; + g_idle_add((GSourceFunc)decarta_idle_geocode_cb, (gpointer)idle_data); + + return LOCATION_ERROR_NONE; +} + +static int +get_geocode_freetext(gpointer handle, + const gchar* addr, + const LocationMapPref *svc_pref, + GList **position_list, + GList **accuracy_list) +{ + DECARTA_LOGD ("get_geocode_freetext"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (position_list, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (accuracy_list, LOCATION_ERROR_PARAMETER); + + int i = 1; + GList *geocode_list = NULL; + LocationPosition *pos = NULL; + LocationAccuracy *acc = NULL; + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + char *language_code = NULL; + char *country_code = NULL; + language_code = location_map_pref_get_language(svc_pref); + country_code = location_map_pref_get_country(svc_pref); + if (language_code == NULL || country_code == NULL) { + gchar tmp_country[3] = ""; + gchar tmp_language[3] = ""; + get_lang(tmp_country, tmp_language); + if (country_code == NULL) { + country_code = g_strdup(tmp_country); + } + if (language_code == NULL) { + language_code = g_strdup(tmp_language); + } + } + + DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, TRUE, addr, NULL); + int ret = decarta_search_geocode(deca_addr, &geocode_list); + decarta_address_free (deca_addr); + + if (ret == DECARTA_ERROR_NONE) { + // libslp-location getting multi addresses. + /* can't change the geocode_list for del */ + GList *tmp_geocode_list = (GList *)geocode_list; + const DecartaGeocode *geocode = NULL; + tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode); + + while (geocode) { + pos = get_location_pos_from_decarta_pos (geocode->pos); + if (geocode->addr) acc = get_location_acc_from_decarta_addr (geocode->addr); + else acc = get_location_acc_from_free_addr (addr); + + DECARTA_LOGD("location decarta plugin: get_geocode_freetext %d, lat %f, lon %f ", i++, pos->latitude, pos->longitude); + + *position_list = g_list_append (*position_list, (gpointer)pos); + *accuracy_list = g_list_append (*accuracy_list, (gpointer)acc); + + if (!tmp_geocode_list) break; + tmp_geocode_list = decarta_geocode_list_next(tmp_geocode_list, &geocode); + } + decarta_geocode_list_free (geocode_list); + } + return convert_decarta_error_to_location_error (ret); +} + + +static int +get_geocode_freetext_async (gpointer handle, + const gchar* addr, + const LocationMapPref *svc_pref, + LocationPositionCB callback, + gpointer userdata) +{ + DECARTA_LOGD("get_geocode_freetext_async"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (callback, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + char *language_code = NULL; + char *country_code = NULL; + language_code = location_map_pref_get_language(svc_pref); + country_code = location_map_pref_get_country(svc_pref); + if (language_code == NULL || country_code == NULL) { + gchar tmp_country[3] = ""; + gchar tmp_language[3] = ""; + get_lang(tmp_country, tmp_language); + if (country_code == NULL) { + country_code = g_strdup(tmp_country); + } + if (language_code == NULL) { + language_code = g_strdup(tmp_language); + } + } + + DecartaData* data = g_new0(DecartaData, 1); + DecartaAddress *deca_addr = decarta_address_new (country_code, language_code, TRUE, addr, NULL); + data->pos_cb = callback; + data->userdata = (gpointer)userdata; + data->userdata2 = (gpointer)get_location_acc_from_decarta_addr (deca_addr); + + // should call decarta_search_geocode_async in idle, OR request may be missed + decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1); + idle_data->addr = deca_addr; + idle_data->geocode_cb = position_cb; + idle_data->decarta_data = data; + g_idle_add((GSourceFunc)decarta_idle_geocode_cb, (gpointer)idle_data); + + return LOCATION_ERROR_NONE; +} + +static int +get_reverse_geocode(gpointer handle, + const LocationPosition *pos, + const LocationMapPref *svc_pref, + LocationAddress **addr, + LocationAccuracy **accuracy) +{ + DECARTA_LOGD("get_reverse_geocode"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(pos, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(addr, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + DecartaGeocode *geocode = NULL; + DecartaPosition *deca_pos = decarta_position_new (pos->latitude, pos->longitude); + int ret = decarta_search_reverse_geocode(deca_pos, &geocode); + decarta_position_free (deca_pos); + + if (ret == DECARTA_ERROR_NONE) { + if (geocode) { + *addr = get_location_addr_from_decarta_addr (geocode->addr); + *accuracy = get_location_acc_from_decarta_addr (geocode->addr); + decarta_geocode_free (geocode); + } + } + return convert_decarta_error_to_location_error (ret); +} + +static gboolean +decarta_idle_reverse_geocode_cb (gpointer data) +{ + DECARTA_LOGD("decarta_idle_reverse_geocode_cb"); + decarta_IdleData* idle_data = (decarta_IdleData*)data; + if (idle_data == NULL || idle_data->decarta_data == NULL) { + DECARTA_LOGD("idle_data or decarta_data is NULL"); + return FALSE; + } + + DecartaData *deca_data = (DecartaData *)idle_data->decarta_data; + int err = decarta_search_reverse_geocode_async (idle_data->pos, idle_data->reverse_geocode_cb, deca_data, &deca_data->handle); + async_request_queue = g_slist_prepend(async_request_queue , deca_data->handle); + if (DECARTA_ERROR_NONE != err) { + DECARTA_LOGD("Decarta Reverse Geocode Failed: %d", err); + + // call address_cb() to return the error code, and free DecartaData + if (idle_data->reverse_geocode_cb) { + idle_data->reverse_geocode_cb (err, NULL, idle_data->decarta_data); + } + } + decarta_position_free (idle_data->pos); + g_free (idle_data); + return FALSE; +} + +static int +get_reverse_geocode_async (gpointer handle, + const LocationPosition *pos, + const LocationMapPref *svc_pref, + LocationAddressCB callback, + gpointer userdata) +{ + DECARTA_LOGD("get_reverse_geocode_async"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(pos, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(callback, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + DecartaData* data = g_new0(DecartaData, 1); + data->addr_cb = callback; + data->userdata = (gpointer)userdata; + DecartaPosition *deca_pos = decarta_position_new (pos->latitude, pos->longitude); + + // should call decarta_search_reverse_geocode_async in idle, OR request may be missed + decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1); + idle_data->pos= deca_pos; + idle_data->reverse_geocode_cb= address_cb; + idle_data->decarta_data = data; + g_idle_add((GSourceFunc)decarta_idle_reverse_geocode_cb, (gpointer)idle_data); + + return LOCATION_ERROR_NONE; +} + + +static DecartaPOIPrefSortOrder +decarta_get_sort_order(LocationPOIPrefSortOrder order) +{ + if (order == LOCATION_POI_PREF_SO_ASC) { + return DECARTA_POI_PREF_SO_ASC; + } else if (order == LOCATION_POI_PREF_SO_DESC) { + return DECARTA_POI_PREF_SO_DESC; + } else { + return DECARTA_POI_PREF_SO_NONE; + } +} + +//to make the request_id unique int, not start with 0 +static guint request_id = 1; + +static gboolean +decarta_idle_directory_cb (gpointer data) +{ + decarta_IdleData* idle_data = (decarta_IdleData*)data; + if (idle_data == NULL) { + g_printf( "decarta_IdleData is NULL\n"); + return FALSE; + } + + int err = decarta_search_directory_async (idle_data->dir_request, idle_data->dir_cb, idle_data->decarta_data); + if (DECARTA_ERROR_NONE != err) { + g_printf( "Decarta Directory Failed: %d\n", err); + + // call landmark_cb() to return the error code, and free DecartaData + if (idle_data->dir_cb) { + char req_id_str[256]; + g_snprintf(req_id_str, 256, "%d", idle_data->request_id); + idle_data->dir_cb (err, req_id_str, NULL, NULL, NULL, idle_data->decarta_data); + } + } + decarta_directory_request_free (idle_data->dir_request); + g_free (idle_data); + return FALSE; +} + +int search_poi(gpointer handle, + const LocationPOIFilter *filter, + const LocationPosition *position, + const LocationMapPref *svc_pref, + const LocationPOIPreference *pref, + LocationPOICB cb, + gpointer user_data, + guint *req_id) +{ + DECARTA_LOGD("location decarta plugin: search_poi"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (position, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + DecartaData* data = g_new0(DecartaData, 1); + DecartaPosition *pos = decarta_position_new (position->latitude, position->longitude); + *req_id = request_id++; + // POI property: keyword, brand, type, description, URL => CATEGORY, KEYWORD, POIName + const char *type = location_poi_filter_get(filter, "CATEGORY"); + const char *keyword = location_poi_filter_get(filter, "KEYWORD"); + const char *poi_name = location_poi_filter_get(filter, "POIName"); + DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL); + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref), + decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref)); + DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST, + DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, 0, *req_id); + decarta_position_free (pos); + decarta_poi_property_free (property); + decarta_poi_preference_free(poi_pref); + + + data->poi_cb = cb; + data->userdata = (gpointer)user_data; + + // should call decarta_search_directory_async in idle, OR request may be missed + decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1); + idle_data->dir_request = dir_request; + idle_data->dir_cb = landmark_cb; + idle_data->decarta_data = data; + idle_data->request_id = request_id; + g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data); + + return LOCATION_ERROR_NONE; +} + +int search_poi_by_area(gpointer handle, + const LocationPOIFilter *filter, + const LocationBoundary *boundary, + const LocationMapPref *svc_pref, + const LocationPOIPreference *pref, + LocationPOICB cb, + gpointer user_data, + guint *req_id) +{ + DECARTA_LOGD("location decarta plugin: search_poi_by_area"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (boundary, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + if (boundary->type == LOCATION_BOUNDARY_CIRCLE) { + DecartaData* data = g_new0(DecartaData, 1); + DecartaPosition *pos = decarta_position_new (boundary->circle.center->latitude, boundary->circle.center->longitude); + double distance = boundary->circle.radius; + DECARTA_LOGD("search_poi_by_area: Circle lat [%lf], lon [%lf], radius [%f]", + boundary->circle.center->latitude, + boundary->circle.center->longitude, + distance); + *req_id = request_id++; + const char *type = location_poi_filter_get(filter, "CATEGORY"); + const char *keyword = location_poi_filter_get(filter, "KEYWORD"); + const char *poi_name = location_poi_filter_get(filter, "POIName"); + DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL); + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref), + decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref)); + DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE, + DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, distance, *req_id); + decarta_position_free (pos); + decarta_poi_property_free (property); + decarta_poi_preference_free(poi_pref); + + data->poi_cb = cb; + data->userdata = (gpointer)user_data; + + // should call decarta_search_directory_async in idle, OR request may be missed + decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1); + idle_data->dir_request = dir_request; + idle_data->dir_cb = landmark_cb; + idle_data->decarta_data = data; + idle_data->request_id = request_id; + g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data); + + return LOCATION_ERROR_NONE; + } else if (boundary->type == LOCATION_BOUNDARY_RECT) { + return LOCATION_ERROR_NOT_AVAILABLE; + } else if (boundary->type == LOCATION_BOUNDARY_POLYGON) { + return LOCATION_ERROR_NOT_AVAILABLE; + } else { + return LOCATION_ERROR_NOT_AVAILABLE; + } +} + +int search_poi_by_address(gpointer handle, + const LocationPOIFilter *filter, + const LocationAddress *addr, + const LocationMapPref *svc_pref, + const LocationPOIPreference *pref, + LocationPOICB cb, + gpointer user_data, + guint *req_id) +{ + DECARTA_LOGD("location decarta plugin: search_poi_by_addr"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (addr, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + char *language_code = NULL; + char *country_code = NULL; + language_code = location_map_pref_get_language(svc_pref); + country_code = location_map_pref_get_country(svc_pref); + if (language_code == NULL || country_code == NULL) { + gchar tmp_country[3] = ""; + gchar tmp_language[3] = ""; + get_lang(tmp_country, tmp_language); + if (country_code == NULL) { + country_code = g_strdup(tmp_country); + } + if (language_code == NULL) { + language_code = g_strdup(tmp_language); + } + } + + DecartaData* data = g_new0(DecartaData, 1); + + // Fixme: landmark_type, landmark_name for decarta_formed_address_new ?? + DecartaFormedAddress *formed_addr = decarta_formed_address_new (addr->building_number, addr->street, addr->country_code, + addr->state, addr->city, addr->district, addr->postal_code, NULL, NULL); + + *req_id = request_id++; + + DecartaAddress *decarta_addr = decarta_address_new (country_code, language_code, FALSE, NULL, formed_addr); + decarta_formed_address_free (formed_addr); + + const char *type = location_poi_filter_get(filter, "CATEGORY"); + const char *keyword = location_poi_filter_get(filter, "KEYWORD"); + const char *poi_name = location_poi_filter_get(filter, "POIName"); + DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL); + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref), + decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref)); + + DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, decarta_addr, NULL, property, 0, *req_id); + decarta_address_free (decarta_addr); + decarta_poi_property_free (property); + decarta_poi_preference_free(poi_pref); + + data->poi_cb = cb; + data->userdata = (gpointer)user_data; + + // should call decarta_search_directory_async in idle, OR request may be missed + decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1); + idle_data->dir_request = dir_request; + idle_data->dir_cb = landmark_cb; + idle_data->decarta_data = data; + idle_data->request_id = request_id; + g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data); + + return LOCATION_ERROR_NONE; +} + +int search_poi_by_freeform(gpointer handle, + const LocationPOIFilter *filter, + const gchar *address, + const LocationMapPref *svc_pref, + const LocationPOIPreference *pref, + LocationPOICB cb, + gpointer user_data, + guint *req_id) +{ + DECARTA_LOGD("location decarta plugin: search_poi_by_freeformed_address"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (filter, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (address, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + char *language_code = NULL; + char *country_code = NULL; + language_code = location_map_pref_get_language(svc_pref); + country_code = location_map_pref_get_country(svc_pref); + if (language_code == NULL || country_code == NULL) { + gchar tmp_country[3] = ""; + gchar tmp_language[3] = ""; + get_lang(tmp_country, tmp_language); + if (country_code == NULL) { + country_code = g_strdup(tmp_country); + } + if (language_code == NULL) { + language_code = g_strdup(tmp_language); + } + } + + DecartaData* data = g_new0(DecartaData, 1); + + *req_id = request_id++; + + DecartaAddress *free_addr = decarta_address_new (country_code, language_code, TRUE, address, NULL); + + const char *type = location_poi_filter_get(filter, "CATEGORY"); + const char *keyword = location_poi_filter_get(filter, "KEYWORD"); + const char *poi_name = location_poi_filter_get(filter, "POIName"); + DecartaPOIProperty *property = decarta_poi_property_new (poi_name, keyword, NULL, type, NULL, NULL); + + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(location_poi_pref_get_max_result(pref), + decarta_get_sort_order(location_poi_pref_get_sort_order(pref)), location_poi_pref_get_sort_by(pref)); + DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, free_addr, NULL, property, 0, *req_id); + + decarta_address_free (free_addr); + decarta_poi_property_free (property); + decarta_poi_preference_free(poi_pref); + + data->poi_cb = cb; + data->userdata = (gpointer)user_data; + + // should call decarta_search_directory_async in idle, OR request may be missed + decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1); + idle_data->dir_request = dir_request; + idle_data->dir_cb = landmark_cb; + idle_data->decarta_data = data; + idle_data->request_id = request_id; + g_idle_add((GSourceFunc)decarta_idle_directory_cb, (gpointer)idle_data); + + return LOCATION_ERROR_NONE; +} + +int cancel_poi_request(gpointer handle, + guint req_id) +{ + DECARTA_LOGD("location decarta plugin: cancel_poi_request"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + + decarta_search_directory_async_cancel (req_id); + return LOCATION_ERROR_NONE; +} + +static void +__route_create_via_list (gpointer data, + gpointer user_data) +{ + LocationPosition *via_loc_pos = (LocationPosition *)data; + GList **via_geocode_list = (GList **)user_data; + + DecartaPosition *via_pos = decarta_position_new (via_loc_pos->latitude, via_loc_pos->longitude); + *via_geocode_list = decarta_geocode_list_append (*via_geocode_list, decarta_geocode_new (via_pos, NULL)); + decarta_position_free (via_pos); +} + +static DecartaRoutePreference +__get_route_type(const gchar *type) +{ + if (0 == g_strcmp0("FASTEST", type)) { + return DECARTA_ROUTE_PREF_FASTEST; + } else if (0 == g_strcmp0("SHORTEST", type)) { + return DECARTA_ROUTE_PREF_SHORTEST; + } else if (0 == g_strcmp0("PEDESTRIAN", type)) { + return DECARTA_ROUTE_PREF_PEDESTRIAN; + } else if (0 == g_strcmp0("AVOID_FREEWAYS", type)) { + return DECARTA_ROUTE_PREF_AVOID_FREEWAYS; + } else if (0 == g_strcmp0("NO_FREEWAYS", type)) { + return DECARTA_ROUTE_PREF_NO_FREEWAYS; + } else if (0 == g_strcmp0("MORE_FREEWAYS", type)) { + return DECARTA_ROUTE_PREF_MORE_FREEWAYS; + } else if (0 == g_strcmp0("IGNORE_PIPES", type)) { + return DECARTA_ROUTE_PREF_IGNORE_PIPES; + } else if (0 == g_strcmp0("EASY", type)) { + return DECARTA_ROUTE_PREF_EASY; + } else { + return DECARTA_ROUTE_PREF_NONE; + } +} + +static gboolean +decarta_idle_route_cb (gpointer data) +{ + decarta_IdleData* idle_data = (decarta_IdleData*)data; + if (idle_data == NULL) { + g_printf( "idle_data is NULL\n"); + return FALSE; + } + + int err = decarta_search_route_async (idle_data->route_request, idle_data->route_cb, idle_data->decarta_data); + if (DECARTA_ERROR_NONE != err) { + g_printf("Decarta Route Failed: %d\n", err); + + // call route_callback() to return the error code, and free DecartaData + if (idle_data->route_cb) { + char req_id_str[256]; + g_snprintf(req_id_str, 256, "%d", idle_data->request_id); + idle_data->route_cb (err, req_id_str, NULL, NULL, NULL, idle_data->decarta_data); + } + } + decarta_route_request_free (idle_data->route_request); + g_free(idle_data); + return FALSE; +} + +int request_route (gpointer handle, + const LocationPosition *origin, + const LocationPosition *destination, + GList *waypoint, + const LocationMapPref *svc_pref, + const LocationRoutePreference *pref, + LocationRouteCB cb, + const gpointer user_data, + guint *req_id) +{ + DECARTA_LOGD("location decarta plugin: request_route"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (origin, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (destination, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (pref, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (cb, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail (req_id, LOCATION_ERROR_PARAMETER); + + char *ID = NULL; + char *password = NULL; + ID = location_map_pref_get_property(svc_pref, "ID"); + password = location_map_pref_get_property(svc_pref, "PASSWORD"); + set_config(ID, password, NULL, NULL); + + char *language_code = NULL; + char *maneuver_rules = NULL; + language_code = location_map_pref_get_language(svc_pref); + if (language_code == NULL) { + gchar tmp_country[3] = ""; + gchar tmp_language[3] = ""; + get_lang(tmp_country, tmp_language); + language_code = g_strdup(tmp_language); + } + if (!g_strcmp0(language_code, "FR")) { + maneuver_rules = g_strdup_printf("maneuver-rules-%s", language_code); + } else { + maneuver_rules = g_strdup("maneuver-rules"); + } + + char *dist_uit = NULL; + dist_uit = location_map_pref_get_distance_unit(svc_pref); + if (g_strcmp0(dist_uit, "KM") != 0 && g_strcmp0(dist_uit, "M") != 0 && g_strcmp0(dist_uit, "DM") != 0 && + g_strcmp0(dist_uit, "MI") != 0 && g_strcmp0(dist_uit, "YD") != 0 && g_strcmp0(dist_uit, "FT") != 0) { + dist_uit = g_strdup("M"); + } + + DecartaData* data = g_new0(DecartaData, 1); + DecartaPosition *start_pos = decarta_position_new (origin->latitude, origin->longitude); + DecartaPosition *end_pos = decarta_position_new (destination->latitude, destination->longitude); + + DecartaGeocode *start = decarta_geocode_new (start_pos, NULL); + DecartaGeocode *end = decarta_geocode_new (end_pos, NULL); + GList *via_geocode_list = NULL; + GList *tmp_waypoint = (GList *)waypoint; + if (tmp_waypoint) { + g_list_foreach(tmp_waypoint, (GFunc)__route_create_via_list, &via_geocode_list); + } + decarta_position_free (start_pos); + decarta_position_free (end_pos); + + gboolean bbox_needed = FALSE; + DecartaPosition *bbox_pos1 = NULL; + DecartaPosition *bbox_pos2 = NULL; + LocationBoundary *bbox = location_route_pref_get_bounding_box(pref); + if (bbox && bbox->type == LOCATION_BOUNDARY_RECT) { + bbox_pos1 = decarta_position_new(bbox->rect.left_top->latitude, bbox->rect.left_top->longitude); + bbox_pos2 = decarta_position_new(bbox->rect.right_bottom->latitude, bbox->rect.right_bottom->longitude); + bbox_needed = TRUE; + } + + float resolution = DEFAULT_ROUTE_RESOLUTION; + char *reslolution_str = (char *)location_route_pref_get_property(pref, (gconstpointer)"resolution"); + if (reslolution_str) { + resolution = (float)g_ascii_strtod(reslolution_str, NULL); + } + + *req_id = request_id++; + DecartaRouteRequest *route_request = decarta_route_request_new (__get_route_type(location_route_pref_get_route_type(pref)), + start, end, via_geocode_list, TRUE, TRUE, + bbox_needed, bbox_pos1, bbox_pos2, TRUE, resolution, TRUE, *req_id, dist_uit, maneuver_rules); + g_free (maneuver_rules); + decarta_geocode_free (start); + decarta_geocode_free (end); + if (via_geocode_list) { + decarta_geocode_list_free (via_geocode_list); + via_geocode_list = NULL; + } + if (bbox_pos1) { + decarta_position_free(bbox_pos1); + } + if (bbox_pos2) { + decarta_position_free(bbox_pos2); + } + + data->route_cb = cb; + data->userdata = (gpointer)user_data; + data->userdata2 = (gpointer)location_position_copy(origin); + data->userdata3 = (gpointer)location_position_copy(destination); + + // should call decarta_search_route_async in idle callback, OR request may be missed + decarta_IdleData* idle_data= g_new0 (decarta_IdleData, 1); + idle_data->route_request = route_request; + idle_data->route_cb= route_callback; + idle_data->decarta_data = data; + idle_data->request_id = request_id; + g_idle_add((GSourceFunc)decarta_idle_route_cb, (gpointer)idle_data); + + return LOCATION_ERROR_NONE; +} +int cancel_route_request (gpointer handle, + guint req_id) +{ + int ret = DECARTA_ERROR_NONE; + + DECARTA_LOGD("location decarta plugin: request_route"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + + ret = decarta_search_route_async_cancel (req_id); + if (ret != DECARTA_ERROR_NONE) { + return convert_decarta_error_to_location_error(ret); + } + + return LOCATION_ERROR_NONE; +} + +static gboolean +is_supported_provider_capability (gpointer handle, LocationMapServiceType type) +{ + DECARTA_LOGD("location decarta plugin: is_supported_provider_capability"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + + return g_capa_list[type]; +} + +static int +get_provider_capability_key (gpointer handle, LocationMapServiceType type, GList **key) +{ + DECARTA_LOGD("location decarta plugin: get_provider_capability_key"); + g_return_val_if_fail(handle == (gpointer)service_name, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail (key, LOCATION_ERROR_PARAMETER); + + gchar **str_key = NULL; + int idx = 0, count = 0; + gchar *available_key = NULL; + + switch (type) { + case MAP_SERVICE_PREF_LANGUAGE: + str_key = key_lang; + count = sizeof(key_lang) / sizeof(char *); + g_printf("key_lang[%d], char *[%d]. Count [%d]", sizeof(key_lang), sizeof(char*), count); + + break; + case MAP_SERVICE_PREF_DISTANCE_UNIT: + case MAP_SERVICE_ROUTE_DISTANCE_UNIT: + str_key = key_dist; + count = sizeof(key_dist) / sizeof(char*); + break; + case MAP_SERVICE_POI_PREF_SORT_BY: + str_key = key_poi_sort; + count = sizeof(key_poi_sort) / sizeof (char*); + break; + case MAP_SERVICE_POI_PREF_PROPERTY: + str_key = key_poi_prop; + count = sizeof(key_poi_prop) / sizeof (char*); + break; + case MAP_SERVICE_POI_FILTER: + str_key = key_poi_filter; + count = sizeof(key_poi_filter) / sizeof (char*); + break; + case MAP_SERVICE_POI_FILTER_CATEGORY: + str_key = key_poi_filter_category; + count = sizeof(key_poi_filter_category) / sizeof (char*); + break; + case MAP_SERVICE_ROUTE_REQUEST_FEATURE_TO_AVOID: + str_key = key_route_feature_to_avoid; + count = sizeof(key_route_feature_to_avoid) / sizeof (char*); + break; + case MAP_SERVICE_ROUTE_PREF_TYPE: + str_key = key_route_type; + count = sizeof(key_route_type) / sizeof (char*); + break; + case MAP_SERVICE_ROUTE_PREF_TRANSPORT_MODE: + str_key = key_route_trans_mode; + count = sizeof(key_route_trans_mode) / sizeof (char*); + break; + default: + str_key = NULL; + break; + } + + if (!str_key) { + *key = NULL; + return LOCATION_ERROR_NOT_FOUND; + } + + for (idx = 0; idx < count; idx++) { + available_key = g_strdup (str_key[idx]); + *key = g_list_append(*key, available_key); + } + + return LOCATION_ERROR_NONE; +} + +LOCATION_MODULE_API gpointer +init (LocModServiceOps* ops) +{ + DECARTA_LOGD("init"); + g_return_val_if_fail(ops, NULL); + gpointer handle = (gpointer)service_name; + + ops->get_service_name = get_service_name; + ops->get_geocode = get_geocode; + ops->get_geocode_freetext = get_geocode_freetext; + ops->get_reverse_geocode = get_reverse_geocode; + ops->get_geocode_async = get_geocode_async; + ops->get_geocode_freetext_async = get_geocode_freetext_async; + ops->get_reverse_geocode_async = get_reverse_geocode_async; + + ops->search_poi = search_poi; + ops->search_poi_by_area = search_poi_by_area; + ops->search_poi_by_address = search_poi_by_address; + ops->search_poi_by_freeform = search_poi_by_freeform; + ops->cancel_poi_request = cancel_poi_request; + + ops->request_route = request_route; + ops->cancel_route_request = cancel_route_request; + + ops->is_supported_provider_capability = is_supported_provider_capability; + ops->get_provider_capability_key = get_provider_capability_key; + + async_request_queue = g_slist_alloc(); + return handle; +} + +static void +cancel_request (gpointer data, gpointer user_data) +{ + decarta_search_geocode_async_cancel(data); + decarta_search_reverse_geocode_async_cancel(data); +} + +LOCATION_MODULE_API void +shutdown (gpointer handle) +{ + DECARTA_LOGD("shutdown"); + g_return_if_fail(handle == (gpointer)service_name); + + g_slist_foreach (async_request_queue, cancel_request, NULL); + + g_slist_free(async_request_queue); +} diff --git a/location_module/location_decarta.h b/location_module/location_decarta.h new file mode 100644 index 0000000..4b7414c --- /dev/null +++ b/location_module/location_decarta.h @@ -0,0 +1,119 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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. + */ + +#ifndef __LOCATION_DECARTA_H__ +#define __LOCATION_DECARTA_H__ + +#include + +#define DEFAULT_ROUTE_RESOLUTION (0.01) + +typedef struct{ + LocationPositionCB pos_cb; + LocationAddressCB addr_cb; + LocationPOICB poi_cb; + LocationRouteCB route_cb; + DecartaHandle *handle; + gpointer userdata; + gpointer userdata2; + gpointer userdata3; +} DecartaData; + +// used to pass the data to idle_callback in async request +typedef struct{ + DecartaPosition *pos; + DecartaAddress *addr; + DecartaDirectoryRequest *dir_request; + DecartaRouteRequest *route_request; + + DecartaReverseGeocodeCB reverse_geocode_cb; + DecartaGeocodeCB geocode_cb; + DecartaDirectoryCB dir_cb; + DecartaRouteCB route_cb; + + void *decarta_data; + guint request_id; +} decarta_IdleData; + +gchar *key_lang[] = { + "KR", + "EN" +}; + +gchar *key_country[] = { + "ko", + "us" +}; + +gchar *key_dist[] = { + "MI", + "M", + "KM", + "YD" +}; + +gchar *key_poi_sort[] = { + "Distance", + "Name" +}; + +gchar *key_poi_prop[] = { + "Distance", + "LandmarkType", + "LandmarkName" +}; + +gchar *key_poi_filter[] = { + "POIName", + "KEYWORD", + "CATEGORY" +}; + +gchar *key_poi_filter_category[] = { + "restaurant", + "cafe" +}; + +gchar *key_route_type[] = { + "FASTEST", + "SHORTEST", + "PEDESTRIAN", + "AVOID_FREEWAYS", + "NO_FREEWAYS", + "MORE_FREEWAYS", + "IGNORE_PIPES", + "EASY" +}; + +gchar *key_route_trans_mode[] = { + "Vehicle", + "Pedestrian" +}; + +gchar *key_route_feature_to_avoid[] = { + "TOLL WAYS", + "BRIDGES" +}; + +#endif + + + diff --git a/packaging/libdecarta.spec b/packaging/libdecarta.spec new file mode 100755 index 0000000..0c0fa06 --- /dev/null +++ b/packaging/libdecarta.spec @@ -0,0 +1,117 @@ +#sbs-git:slp/pkgs/l/libdecarta libdecarta 0.2.7 93c14f62407c43d9d2634d6c480fd322ca965c0b +%define _optdir /opt +%define _etcdir /etc +%define _appdir %{_optdir}/apps +%define _moduledir %{_libdir}/location/module + + +Name: libdecarta +Summary: Decarta Web Service Library (Shared Object) +Version: 0.2.7 +Release: 0 +Group: TO_BE/FILLED_IN +License: TO BE FILLED IN +Source0: %{name}-%{version}.tar.gz +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +BuildRequires: libgcrypt-devel +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(libsoup-2.4) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(gconf-2.0) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(edje) +BuildRequires: pkgconfig(location) + +%description +Decarta Web Service Library + + +%package devel +Summary: Decarta Web Service Library (Development Headers) +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description devel +Decarta Web Service Library Development Package + +%package -n docrypt +Summary: Simple encryption tool +Group: TO_BE/FILLED_IN + +%description -n docrypt +Description: Simple encryption tool + +%package -n elementary-decarta +Summary: elementary map module for decarta +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description -n elementary-decarta +Description: elementary map module for decarta + +%package -n location-decarta +Summary: location geocode module for decarta +Group: TO_BE/FILLED_IN +Requires: %{name} = %{version}-%{release} + +%description -n location-decarta +Description: location geocode module for decarta + +%prep +%setup -q + +%build +./autogen.sh +%configure --disable-static \ + --enable-dlog \ + --enable-debug \ + APP_DIR=%{_appdir} \ + APP_CONF_DIR=res/.decarta \ + DEF_CONF_DIR=%{_etcdir}/decarta + +make %{?jobs:-j%jobs} + + +%install +rm -rf %{buildroot} +%make_install + +%post +mkdir -p %{_moduledir} +ln -sf %{_moduledir}/libmap-service-decarta.so %{_moduledir}/libmap-service.so + +%files +%defattr(-,root,root,-) +%{_libdir}/libdecarta.so.0.0.0 +%{_libdir}/libdecarta.so.0 +%{_libdir}/libdecarta.so + + +%files devel +%defattr(-,root,root,-) +%{_includedir}/decarta/decarta_geocode.h +%{_includedir}/decarta/decarta.h +%{_includedir}/decarta/decarta_directory.h +%{_includedir}/decarta/decarta_maps.h +%{_includedir}/decarta/decarta_types.h +%{_includedir}/decarta/decarta_route.h +%{_libdir}/pkgconfig/decarta.pc + +%files -n docrypt +%defattr(-,root,root,-) +%{_bindir}/docrypt + +%files -n elementary-decarta +%defattr(-,root,root,-) +%ifarch %{arm} +%{_libdir}/elementary/modules/decarta-normal/linux-gnueabi-armv7l-0.7.0/module.so +%else +%{_libdir}/elementary/modules/decarta-normal/linux-gnu-i686-0.7.0/module.so +%endif + +%files -n location-decarta +%defattr(-,root,root,-) +%{_moduledir}/libmap-service* diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..c27aa33 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,11 @@ +dir_decarta = $(top_srcdir)/decarta +noinst_PROGRAMS = decarta_test + +decarta_test_SOURCES = decarta_test.c + +AM_CFLAGS = \ + -I$(dir_decarta)\ + $(TEST_CFLAGS) +LDADD = \ + $(dir_decarta)/libdecarta.la \ + $(TEST_LIBS) diff --git a/tests/decarta_test.c b/tests/decarta_test.c new file mode 100755 index 0000000..67b129b --- /dev/null +++ b/tests/decarta_test.c @@ -0,0 +1,967 @@ +/* + * libdecarta + * + * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune Kim + * + * 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 +#include +#include +#include +#include +#include + +#define STR_MAX 128 +static GMainLoop *g_mainloop = NULL; + +#define GCONF_PROXY_MODE "/system/proxy/mode" +#define GCONF_HTTP_PROXY_HOST "/system/http_proxy/host" +#define GCONF_HTTP_PROXY_PORT "/system/http_proxy/port" +#define ENV_HTTP_PROXY "http_proxy" + +#define DECARTA_XML_LOG "DECARTA_XML_LOG" + + +/* +* network operations +*/ +static bool net_state = false; /* save the network status */ +static connection_h net_hand = NULL; + +#if 1 // fixme: some issues, can't can't detect connecetion +static void __map_connection_cb(const connection_network_param_e param, void *user_data) +{ + + bool state = false; + state = connection_is_connected(); + switch (param) { + case CONNECTION_NETWORK_STATUS: + if (state) { + /* connect successful */ + g_printf("[deCarta test] Network connect successful\n"); + net_state = true; + } else { + /* connection failed */ + g_printf("[deCarta test] Network connect fail\n"); + net_state = false; + } + break; + case CONNECTION_IP_ADDRESS: + case CONNECTION_PROXY_ADDRESS: + break; + default: + break; + } +} + + +static void _map_connect_to_network(void) +{ + + int ret ; + ret = connection_create(&net_hand); + if (ret != CONNECTION_ERROR_NONE) { + /*connect failed*/ + g_printf("[deCarta test] Network connect failed\n"); + } + + ret = connection_set_cb(net_hand, __map_connection_cb, NULL); //3rd: ud + if (ret != CONNECTION_ERROR_NONE) { + /*register failed*/ + g_printf("[deCarta test] Network register failed\n"); + } + +} +#endif + +static void _map_connect_destroy(void) +{ + if (net_hand) { + connection_unset_cb(net_hand); + connection_destroy(net_hand); + } +} + + +/* +* deCarta test code +*/ + +gboolean +exit_program (gpointer data) +{ + g_main_loop_quit (g_mainloop); + g_debug ("Quit g_mainloop"); + return FALSE; +} + +gpointer GmainThread(gpointer data) +{ + g_mainloop = g_main_loop_new (NULL, FALSE); + g_printf("\n...Entering GMain Loop to Receive Notifications....\n"); + g_main_loop_run (g_mainloop); + g_main_loop_unref (g_mainloop); + g_mainloop = NULL; + return NULL; +} + +void SelectOpt(char* buf) +{ + int iLen = 0; + fgets(buf, 255, stdin); + iLen = g_utf8_strlen(buf, -1); + buf[iLen-1] = '\0'; +} + +int PromptInt() +{ + char buf[255]; + int ret; + fgets(buf, 255, stdin); + ret = g_ascii_strtoll(buf, NULL, 10); + return ret; +} + +double PromptDB() +{ + char buf[255]; + double ret; + fgets(buf, 255, stdin); + ret = g_ascii_strtod(buf, NULL); + return ret; +} + +static void +print_address (const DecartaAddress *addr) +{ + if (!addr) return; + if (addr->is_freerorm) + g_printf("Address: %s %s %s\n", addr->country_code, addr->language_code, addr->freeform_address); + else + g_printf("Address: %s %s %s %s %s %s %s %s %s %s %s\n", + addr->country_code, addr->language_code, addr->formed_addr->street_number, + addr->formed_addr->street_name, addr->formed_addr->state, addr->formed_addr->county, addr->formed_addr->city, + addr->formed_addr->district, addr->formed_addr->postal_code, addr->formed_addr->landmark_type, addr->formed_addr->landmark_name); +} + +static void +print_position (const DecartaPosition *pos) +{ + if (!pos) return; + g_printf("Position: %lf %lf\n", pos->latitude, pos->longitude); +} + +static void +print_position_list (const GList *pos_list) +{ + const DecartaPosition *pos = NULL; + pos_list = decarta_position_list_next(pos_list, &pos); + g_printf("--------- Position List -------------\n"); + while (pos) { + print_position (pos); + if (!pos_list) break; + pos_list = decarta_position_list_next(pos_list, &pos); + } +} + +static void +print_geocode_list (const GList *geocode_list) +{ + const DecartaGeocode *geocode = NULL; + geocode_list = decarta_geocode_list_next(geocode_list, &geocode); + g_printf("--------- Geocode List -------------\n"); + while (geocode) { + print_position (geocode->pos); + print_address (geocode->addr); + geocode = NULL; + g_printf("----------------------\n"); + if (!geocode_list) break; + geocode_list = decarta_geocode_list_next(geocode_list, &geocode); + } +} + +static void +print_poi_list (const GList *poi_list) +{ + const DecartaPOI *poi = NULL; + poi_list = decarta_poi_list_next (poi_list, &poi); + g_printf("-------- POI list --------\n"); + while (poi) + { + g_printf("name:%s id:%s phone_number:%s\n", poi->name, poi->id, poi->phone_number); + char *key = NULL; + char *value = NULL; + decarta_poi_info_table_iter_init (poi->info_list); + while (decarta_poi_info_list_table_next (poi->info_list, &key, &value)) + { + g_printf("%s=%s\n", key, value); + } + if(poi->pos) print_position (poi->pos); + if (poi->addr) print_address (poi->addr); + g_printf("----------------------\n"); + if (!poi_list) break; + poi_list = decarta_poi_list_next (poi_list, &poi); + } +} + +static void +print_map (const DecartaMap *map) +{ + if (map->center) { + g_printf ("Cetner Positoin: "); + print_position (map->center); + } + if (map->box_corner1 && map->box_corner2) { + g_print ("BoundingBox\n"); + print_position (map->box_corner1); + print_position (map->box_corner2); + } + g_print ("Radius: %f\n", map->radius); + g_print ("tile_url: %s\n", map->tile_url); +} + +static void +print_instructioon (const DecartaRouteInstructions *inst) +{ + if (!inst) return; + g_printf ("tour:%s\n", inst->tour); + g_printf ("duration:%u, distance:%f\n", inst->duration, inst->distance); + g_printf ("instruction:%s\n", inst->instruction); + if (inst->map) print_map (inst->map); +} + +static void +print_instructioon_list (const GList *inst_list) +{ + const DecartaRouteInstructions *inst = NULL; + inst_list = decarta_route_instructions_list_next( inst_list, &inst); + g_printf("--------- Instruction List -------------\n"); + while (inst) { + print_instructioon (inst); + g_printf("----------------------\n"); + if (!inst_list) break; + inst_list = decarta_route_instructions_list_next (inst_list, &inst); + } +} + +static void +print_route (const DecartaRoute *route) +{ + g_printf("Total time: %u, Total Distance: %f\n", route->total_time, route->total_distance); + if (route->start_geo_list) { + g_print("============= Start Geocode List ============= \n"); + print_geocode_list(route->start_geo_list); + } + if (route->end_geo_list) { + g_print("============= End Geocode List =============\n"); + print_geocode_list(route->end_geo_list); + } + if (route->box_corner1) { + g_print("Bounding Box Corner1: "); + print_position(route->box_corner1); + } + if (route->box_corner2) { + g_print("Bounding Box Corner2: "); + print_position(route->box_corner2); + } + if (route->overview) { + g_print("============= Overview Map =============\n"); + print_map (route->overview); + } + if (route->line_pos_list) { + g_print("============= Line position List =============\n"); + print_position_list (route->line_pos_list); + } + if (route->instructions_list) { + g_print("============= Instructions List =============\n"); + print_instructioon_list (route->instructions_list); + } + +} + +typedef struct{ + DecartaPosition *pos; + DecartaAddress *addr; + DecartaDirectoryRequest *dir_request; + DecartaRouteRequest *route_request; + int zoom; + + DecartaReverseGeocodeCB reverse_geocode_cb; + DecartaGeocodeCB geocode_cb; + //LocationPOICB dir_cb; + DecartaDirectoryCB dir_cb; + DecartaMapCB map_cb; + DecartaRouteCB route_cb; + void *user_data; + + DecartaHandle *handle; + DecartaBoundary *boundary; +} IdleData; + +static void +reverse_geocode_cb (DecartaError error, const DecartaGeocode *geocode, void *userdata) +{ + g_printf("\n===== reverse_geocode_cb ======\n"); + if (error != DECARTA_ERROR_NONE) { + g_printf("Failed :%d\n", error); + return; + } + g_printf("Success, geocode[0x%x] user_data[0x%x]\n", (unsigned int)geocode, (unsigned int)userdata); + print_position (geocode->pos); + print_address (geocode->addr); +} + +static void +geocode_cb (DecartaError error, const GList *geocode_list, void *userdata) +{ + g_printf("\n===== geocode_cb ======\n"); + if (error != DECARTA_ERROR_NONE) { + g_printf("Failed :%d\n", error); + return; + } + g_printf("Success, poi_list[0x%x] user_data[0x%x]\n", (unsigned int)geocode_list, (unsigned int)userdata); + print_geocode_list (geocode_list); +} + + +static void +directory_cb(DecartaError error, const gchar *req_id_str, const GList* poi_list, const gchar *error_code, const gchar *error_msg, void *userdata) +{ + g_printf("\n===== decarta test: directory_cb ======\n"); + if (error != DECARTA_ERROR_NONE) { + g_printf("Failed :%d\n", error); + return; + } + g_printf("Success, poi_list[0x%x] user_data[0x%x]\n", (unsigned int)poi_list, (unsigned int)userdata); + //print_poi_list (poi_list); +} + +static void +map_cb (DecartaError error, const DecartaMap *map, void *userdata) +{ + g_printf("\n===== map_cb ======\n"); + if (error != DECARTA_ERROR_NONE) { + g_printf("Failed :%d\n", error); + return; + } + g_printf("Success, map[0x%x] user_data[0x%x]\n", (unsigned int)map, (unsigned int)userdata); + print_map (map); +} + +static void +route_cb (DecartaError error, const gchar *req_id_str, const DecartaRoute *route, const gchar * error_code, const gchar * error_msg, void *userdata) +{ + g_printf("\n===== route_cb ======\n"); + if (error != DECARTA_ERROR_NONE) { + g_printf("Failed :%d\n", error); + return; + } + g_printf("Success, route[0x%x] user_data[0x%x]\n", (unsigned int)route, (unsigned int)userdata); + print_route (route); +} + +static gboolean +idle_reverse_geocode (gpointer data) +{ + IdleData* idle_data = (IdleData*)data; + int err = decarta_search_reverse_geocode_async (idle_data->pos, idle_data->reverse_geocode_cb, idle_data->user_data, &idle_data->handle); + if (DECARTA_ERROR_NONE != err) g_printf("Failed: %d\n", err); + decarta_position_free (idle_data->pos); + g_free (idle_data); + return FALSE; +} + +static gboolean +idle_directory (gpointer data) +{ + IdleData* idle_data = (IdleData*)data; + int err = decarta_search_directory_async (idle_data->dir_request, idle_data->dir_cb, idle_data->user_data); + if (DECARTA_ERROR_NONE != err) g_printf( "Failed: %d\n", err); + decarta_directory_request_free (idle_data->dir_request); + g_free (idle_data); + return FALSE; +} + +static gboolean +idle_geocode (gpointer data) +{ + IdleData* idle_data = (IdleData*)data; + int err = decarta_search_geocode_async(idle_data->addr, idle_data->geocode_cb, idle_data->user_data, &idle_data->handle); + if (DECARTA_ERROR_NONE != err) g_printf("Failed: %d\n", err); + decarta_address_free (idle_data->addr); + g_free(idle_data); + return FALSE; +} + +static gboolean +idle_map (gpointer data) +{ + IdleData* idle_data = (IdleData*)data; + int err = decarta_search_map_async (idle_data->pos, idle_data->zoom, idle_data->map_cb, idle_data->user_data); + if (DECARTA_ERROR_NONE != err) g_printf("Failed: %d\n", err); + decarta_position_free (idle_data->pos); + g_free(idle_data); + return FALSE; +} + +static gboolean +idle_route (gpointer data) +{ + IdleData* idle_data = (IdleData*)data; + int err = decarta_search_route_async (idle_data->route_request, idle_data->route_cb, idle_data->user_data); + if (DECARTA_ERROR_NONE != err) g_printf("Failed: %d\n", err); + decarta_route_request_free (idle_data->route_request); + g_free(idle_data); + return FALSE; +} + +int main(int argc, char** argv) +{ + char strOpt[255]; + GError *gerr = NULL; + IdleData* data_rev_geo = NULL; + IdleData* data_geo = NULL; + + g_setenv("PKG_NAME", "com.samsung.decarta_test", 1); + + g_type_init(); + if( !g_thread_supported() ) + { + g_thread_init(NULL); + } + + //net_open(); + net_state = connection_is_connected(); + if (net_state) { + /* connected, go through */ + } else { + /* wait for connection */ + #if 1 + _map_connect_to_network(); + + //fixme: some issues, bypass first + g_printf("Waiting for network connection\n"); + while(net_state == false) { + sleep(10); + g_printf("."); + } + g_printf("Network wait over\n"); + #endif + } + + g_setenv(DECARTA_XML_LOG, "1", TRUE); // output the XML log + + GThread *g_main; + g_main = g_thread_create(GmainThread, NULL, TRUE, &gerr); + if(g_main == NULL) + { + g_debug("Error create gmain thread: Err domain[%d] Err code[%d] Err msg[%s]", + gerr->domain, gerr->code, gerr->message); + g_error_free(gerr); + return 0; + } + + g_printf("---MO: Start Decarta Test App ---\n"); + while(1) + { + g_printf("\n================================= Decarta API Test =================================\n"); + g_printf("0. Exit\n"); + g_printf("1. decarta_search_reverse_geocode\n"); + g_printf("1a. decarta_search_reverse_geocode_async\n"); + g_printf("11. decarta_search_reverse_geocode_async_cancel\n"); + g_printf("------------------------------------------------------------------------------------\n"); + g_printf("2. decarta_search_geocode (structured)\n"); + g_printf("3. decarta_search_geocode (free-formed)\n"); + g_printf("2a. decarta_search_geocode_async (structured)\n"); + g_printf("3a. decarta_search_geocode_async (free-formed)\n"); + g_printf("33. decarta_search_geocode_async_cancel\n"); + g_printf("------------------------------------------------------------------------------------\n"); + g_printf("4. decarta_search_directory (nearest position)\n"); + g_printf("4a. decarta_search_directory_async (nearest position)\n"); + g_printf("4b. decarta_search_directory_async (nearest address)\n"); + g_printf("4c. decarta_search_directory_async (nearest freeformed address)\n"); + g_printf("4d. decarta_search_directory_async (ADDRESS address directly)\n"); + g_printf("4e. decarta_search_directory_async (ADDRESS freeformed address directly)\n"); + g_printf("4f. decarta_search_directory_async (WithinBoundary rect)\n"); + g_printf("4g. decarta_search_directory_async (WithinBoundary circle)\n"); + g_printf("4h. decarta_search_directory_async (WithinBoundary polygon)\n"); + g_printf("4x. decarta_search_directory_async (withindistance position)\n"); + g_printf("4y. decarta_search_directory_async (withindistance address)\n"); + g_printf("4z. decarta_search_directory_async (withindistance freeformed address)\n"); + g_printf("44. decarta_search_directory_async_cancel\n"); + g_printf("------------------------------------------------------------------------------------\n"); + g_printf("5. decarta_route_request (position)(return route, instructions with map)\n"); + g_printf("5a. decarta_route_request (address) (return route)\n"); + g_printf("5b. decarta_route_request (via) (return instructions with map)\n"); + g_printf("5c. decarta_route_request (mixed) (return only summary)\n"); + g_printf("5w. decarta_route_request_async (position)(return route, instructions with map)\n"); + g_printf("5x. decarta_route_request_async (address) (return route)\n"); + g_printf("5y. decarta_route_request_async (via) (return instructions with map)\n"); + g_printf("5z. decarta_route_request_async (mixed) (return only summary)\n"); + g_printf("55. decarta_search_route_async_cancel\n"); + g_printf("------------------------------------------------------------------------------------\n"); + g_printf("6. decarta_search_map\n"); + g_printf("6a. decarta_search_map_async\n"); + g_printf("66. decarta_search_map_async_cancel\n"); + g_printf("====================================================================================\n"); + g_printf("Select option: "); + SelectOpt(strOpt); + g_printf("====================================================================================\n"); + if (0 == g_strcmp0("1",strOpt)) { + DecartaPosition *pos = decarta_position_new (37.335276, -121.890059); + DecartaGeocode *geocode = NULL; + int err = decarta_search_reverse_geocode(pos, &geocode); + decarta_position_free (pos); + + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_position (geocode->pos); + print_address (geocode->addr); + decarta_geocode_free (geocode); + } else g_printf("Failed: %d\n", err); + } else if (0 == g_strcmp0("1a",strOpt)) { + //IdleData* data_rev_geo = g_new0(IdleData, 1); + data_rev_geo = g_new0(IdleData, 1); + data_rev_geo->pos = decarta_position_new (37.335276, -121.890059); + data_rev_geo->reverse_geocode_cb = reverse_geocode_cb; + data_rev_geo->user_data = NULL; + g_idle_add((GSourceFunc)idle_reverse_geocode, (gpointer)data_rev_geo); + } else if (0 == g_strcmp0("11",strOpt)) { + decarta_search_reverse_geocode_async_cancel(data_rev_geo->handle); + } else if (0 == g_strcmp0("2",strOpt)) { + DecartaFormedAddress *formed_addr = decarta_formed_address_new ("1", "Post Street", "CA", NULL, "san jose", NULL, "95113", NULL, NULL); + DecartaAddress *addr = decarta_address_new ("US", "EN", FALSE, NULL, formed_addr); + decarta_formed_address_free (formed_addr); + GList *geocode_list = NULL; + int err = decarta_search_geocode(addr, &geocode_list); + decarta_address_free (addr); + + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_geocode_list (geocode_list); + decarta_geocode_list_free (geocode_list); + } else g_printf("Failed: %d\n", err); + } else if (0 == g_strcmp0("3",strOpt)) { + DecartaAddress *addr = decarta_address_new ("US", "EN", TRUE, "4 N 2nd Street 95113", NULL); + GList *geocode_list = NULL; + int err = decarta_search_geocode(addr, &geocode_list); + decarta_address_free (addr); + + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_geocode_list (geocode_list); + decarta_geocode_list_free (geocode_list); + } else g_printf("Failed: %d\n", err); + } else if (0 == g_strcmp0("2a",strOpt)) { + //IdleData* data = g_new0(IdleData, 1); + data_geo = g_new0(IdleData, 1); + DecartaFormedAddress *formed_addr = decarta_formed_address_new ("1", "Post Street", "CA", NULL, "san jose", NULL, "95113", NULL, NULL); + data_geo->addr = decarta_address_new ("US", "EN", FALSE, NULL, formed_addr); + decarta_formed_address_free (formed_addr); + data_geo->geocode_cb = geocode_cb; + data_geo->user_data = NULL; + g_idle_add((GSourceFunc)idle_geocode, (gpointer)data_geo); + } else if (0 == g_strcmp0("3a",strOpt)) { + //IdleData* data = g_new0(IdleData, 1); + data_geo = g_new0(IdleData, 1); + data_geo->addr = decarta_address_new ("US", "EN", TRUE, "4 N 2nd Street 95113", NULL); + data_geo->geocode_cb = geocode_cb; + data_geo->user_data = NULL; + g_idle_add((GSourceFunc)idle_geocode, (gpointer)data_geo); + } else if (0 == g_strcmp0("33",strOpt)) { + decarta_search_geocode_async_cancel(data_geo->handle); + } else if (0 == g_strcmp0("4",strOpt)) { + DecartaPosition *pos = decarta_position_new (37.336723, -121.889555); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 11; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(2, DECARTA_POI_PREF_SO_ASC, "Distance"); + DecartaDirectoryRequest *dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST, + DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, 0, req_id); + decarta_position_free (pos); + decarta_poi_property_free (property); + GList *poi_list = NULL; + int err = decarta_search_directory (dir_request, &poi_list); + decarta_directory_request_free (dir_request); + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_poi_list (poi_list); + decarta_poi_list_free (poi_list); + } else g_printf("Failed: %d\n", err); + } else if (0 == g_strcmp0("4a",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaPosition *pos = decarta_position_new (37.336723, -121.889555); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 12; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(2, DECARTA_POI_PREF_SO_DESC, "Distance"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST, + DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, 0, req_id); + decarta_position_free (pos); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("4b",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaFormedAddress *formed_addr = decarta_formed_address_new ("51", + "N SAN PEDRO ST", "CA", "SANTA CLARA", "SAN JOSE", NULL, "95110", "RESTAURANT", "TIED HOUSE CAFE & BREWERY"); + DecartaAddress *addr = decarta_address_new ("US", "EN", FALSE, NULL, formed_addr); + decarta_formed_address_free (formed_addr); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 13; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(3, DECARTA_POI_PREF_SO_DESC, "Name"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, addr, NULL, property, 0, req_id); + decarta_address_free (addr); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("4c",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaAddress *addr = decarta_address_new ("US", "EN", TRUE, "N SAN PEDRO ST CA SANTA CLARA SAN JOSE 95110", NULL); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 14; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(8, DECARTA_POI_PREF_SO_ASC, "Distance"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_NEAREST, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, addr, NULL, property, 0, req_id); + decarta_address_free (addr); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("4d",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaFormedAddress *formed_addr = decarta_formed_address_new ("51", + "N SAN PEDRO ST", "CA", "SANTA CLARA", "SAN JOSE", NULL, "95110", "RESTAURANT", "TIED HOUSE CAFE & BREWERY"); + DecartaAddress *addr = decarta_address_new ("US", "EN", FALSE, NULL, formed_addr); + decarta_formed_address_free (formed_addr); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 15; + // SortCriterion 'Type' not supported, + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(20, DECARTA_POI_PREF_SO_DESC, "Type"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, addr, NULL, property, 0, req_id); + decarta_address_free (addr); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("4e",strOpt)) { + + IdleData* data= g_new0 (IdleData, 1); + DecartaAddress *addr = decarta_address_new ("US", "EN", TRUE, "North Second St.", NULL); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "restaurant", NULL, NULL, NULL, NULL); + guint req_id = 16; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(25, DECARTA_POI_PREF_SO_ASC, "Distance"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_ADDRESS, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, addr, NULL, property, 0, req_id); + decarta_address_free (addr); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("4f",strOpt)) { + // WithinBoundary rect, 120209, unimplemented by deCarta ??? + IdleData* data= g_new0 (IdleData, 1); + + DecartaPosition *rb = decarta_position_new(37.255, 127.056); + DecartaPosition *lt = decarta_position_new(37.260, 127.050); + DecartaBoundary *bound = decarta_boundary_new_for_rect(lt, rb); + decarta_position_free (rb); + decarta_position_free (lt); + + //DecartaPosition *pos = decarta_position_new (37.336723, -121.889555); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 17; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(10, DECARTA_POI_PREF_SO_DESC, "Type"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_BOUNDARY, + DECARTA_DIRECTORY_TYPE_BOUNDARY, NULL, NULL, bound, property, 400, req_id); + //decarta_position_free (pos); + decarta_boundary_free(bound); //location_boundary_free + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + data->boundary = bound; // 120209 + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("4g",strOpt)) { + // WithinBoundary circle, 120209 + #if 0 + IdleData* data= g_new0 (IdleData, 1); + DecartaFormedAddress *formed_addr = decarta_formed_address_new ("51", + "N SAN PEDRO ST", "CA", "SANTA CLARA", "SAN JOSE", NULL, "95110", "RESTAURANT", "TIED HOUSE CAFE & BREWERY"); + DecartaAddress *addr = decarta_address_new ("US", "EN", FALSE, NULL, formed_addr); + decarta_formed_address_free (formed_addr); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 18; + data->dir_request = decarta_directory_request_new (NULL, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_BOUNDARY, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, addr, bound, property, 400, req_id); + decarta_address_free (addr); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + data->boundary = bound; // 120209 + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + #endif + } else if (0 == g_strcmp0("4h",strOpt)) { + // WithinBoundary polygon, 120209 + #if 0 + IdleData* data= g_new0 (IdleData, 1); + DecartaAddress *addr = decarta_address_new ("US", "EN", TRUE, "N SAN PEDRO ST CA SANTA CLARA SAN JOSE 95110", NULL); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 19; + data->dir_request = decarta_directory_request_new (NULL, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_BOUNDARY, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, addr, bound, property, 2000, req_id); + decarta_address_free (addr); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + data->boundary = bound; // 120209 + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + #endif + } else if (0 == g_strcmp0("4x",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaPosition *pos = decarta_position_new (37.336723, -121.889555); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 20; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(10, 1, "Distance"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE, + DECARTA_DIRECTORY_TYPE_POS, pos, NULL, NULL, property, 400, req_id); + decarta_position_free (pos); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("4y",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaFormedAddress *formed_addr = decarta_formed_address_new ("51", + "N SAN PEDRO ST", "CA", "SANTA CLARA", "SAN JOSE", NULL, "95110", "RESTAURANT", "TIED HOUSE CAFE & BREWERY"); + DecartaAddress *addr = decarta_address_new ("US", "EN", FALSE, NULL, formed_addr); + decarta_formed_address_free (formed_addr); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 21; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(10, 1, "Distance"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, addr, NULL, property, 400, req_id); + decarta_address_free (addr); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("4z",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaAddress *addr = decarta_address_new ("US", "EN", TRUE, "N SAN PEDRO ST CA SANTA CLARA SAN JOSE 95110", NULL); + DecartaPOIProperty *property = decarta_poi_property_new (NULL, "cafe", NULL, NULL, NULL, NULL); + guint req_id = 22; + DecartaPOIPreference *poi_pref = decarta_poi_preference_new(10, 1, "Distance"); + data->dir_request = decarta_directory_request_new (poi_pref, DECARTA_DIRECTORY_SEARCH_TYPE_WITHIN_DISTANCE, + DECARTA_DIRECTORY_TYPE_ADDRESS, NULL, addr, NULL, property, 2000, req_id); + decarta_address_free (addr); + decarta_poi_property_free (property); + data->dir_cb = directory_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_directory, (gpointer)data); + } else if (0 == g_strcmp0("44",strOpt)) { + decarta_search_directory_async_cancel (10); // fixme: request_id dummy + } else if (0 == g_strcmp0("5",strOpt)) { + DecartaPosition *start_pos = decarta_position_new (37.336723, -121.889555); + DecartaPosition *end_pos = decarta_position_new (37.33461, -121.876445); + DecartaGeocode *start = decarta_geocode_new (start_pos, NULL); + DecartaGeocode *end = decarta_geocode_new (end_pos, NULL); + decarta_position_free (start_pos); + decarta_position_free (end_pos); + guint req_id = 23; + DecartaRouteRequest *request = decarta_route_request_new (DECARTA_ROUTE_PREF_FASTEST, start, end, NULL, TRUE, TRUE, + FALSE, NULL, NULL, FALSE, 0, FALSE, req_id, "M", "maneuver-rules"); + decarta_geocode_free (start); + decarta_geocode_free (end); + DecartaRoute *route = NULL; + int err = decarta_search_route (request, &route); + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_route (route); + decarta_route_free (route); + } else g_printf("Failed: %d\n", err); + decarta_route_request_free (request); + } else if (0 == g_strcmp0("5a",strOpt)) { + DecartaAddress *start_addr = decarta_address_new ("US", "EN", TRUE, "1600 Amphitheatre Parkway, 94043", NULL); + DecartaAddress *end_addr = decarta_address_new ("US", "EN", TRUE, "4 North Second St, 95113", NULL); + DecartaGeocode *start = decarta_geocode_new (NULL, start_addr); + DecartaGeocode *end = decarta_geocode_new (NULL, end_addr); + decarta_address_free (start_addr); + decarta_address_free (end_addr); + guint req_id = 24; + DecartaRouteRequest *request = decarta_route_request_new (DECARTA_ROUTE_PREF_FASTEST, start, end, NULL, TRUE, FALSE, + FALSE, NULL, NULL, FALSE, 0, FALSE, req_id, "M", "maneuver-rules"); + decarta_geocode_free (start); + decarta_geocode_free (end); + DecartaRoute *route = NULL; + int err = decarta_search_route (request, &route); + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_route (route); + decarta_route_free (route); + } else g_printf("Failed: %d\n", err); + decarta_route_request_free (request); + } else if (0 == g_strcmp0("5b",strOpt)) { + DecartaPosition *start_pos = decarta_position_new (37.336723, -121.889555); + DecartaPosition *end_pos = decarta_position_new (37.33461, -121.876445); + DecartaPosition *via_pos = decarta_position_new (37.329475, -121.891444); + DecartaGeocode *start = decarta_geocode_new (start_pos, NULL); + DecartaGeocode *end = decarta_geocode_new (end_pos, NULL); + GList *via_geocode_list = decarta_geocode_list_append (NULL, decarta_geocode_new (via_pos, NULL)); + decarta_position_free (start_pos); + decarta_position_free (end_pos); + decarta_position_free (via_pos); + guint req_id = 25; + DecartaRouteRequest *request = decarta_route_request_new (DECARTA_ROUTE_PREF_FASTEST, start, end, via_geocode_list, FALSE, TRUE, + FALSE, NULL, NULL, FALSE, 0, FALSE, req_id, "M", "maneuver-rules"); + decarta_geocode_free (start); + decarta_geocode_free (end); + decarta_geocode_list_free (via_geocode_list); + DecartaRoute *route = NULL; + int err = decarta_search_route (request, &route); + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_route (route); + decarta_route_free (route); + } else g_printf("Failed: %d\n", err); + decarta_route_request_free (request); + } else if (0 == g_strcmp0("5c",strOpt)) { + DecartaAddress *start_addr = decarta_address_new ("US", "EN", TRUE, "1600 Amphitheatre Parkway, 94043", NULL); + DecartaPosition *end_pos = decarta_position_new (37.336850, -121.889591); + DecartaGeocode *start = decarta_geocode_new (NULL, start_addr); + DecartaGeocode *end = decarta_geocode_new (end_pos, NULL); + decarta_address_free (start_addr); + decarta_position_free (end_pos); + guint req_id = 26; + DecartaRouteRequest *request = decarta_route_request_new (DECARTA_ROUTE_PREF_FASTEST, start, end, NULL, FALSE, FALSE, + FALSE, NULL, NULL, FALSE, 0, FALSE, req_id, "M", "maneuver-rules"); + decarta_geocode_free (start); + decarta_geocode_free (end); + DecartaRoute *route = NULL; + int err = decarta_search_route (request, &route); + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_route (route); + decarta_route_free (route); + } else g_printf("Failed: %d\n", err); + decarta_route_request_free (request); + } else if (0 == g_strcmp0("5w",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaPosition *start_pos = decarta_position_new (37.336723, -121.889555); + DecartaPosition *end_pos = decarta_position_new (37.33461, -121.876445); + DecartaGeocode *start = decarta_geocode_new (start_pos, NULL); + DecartaGeocode *end = decarta_geocode_new (end_pos, NULL); + decarta_position_free (start_pos); + decarta_position_free (end_pos); + guint req_id = 27; + data->route_request = decarta_route_request_new (DECARTA_ROUTE_PREF_FASTEST, start, end, NULL, TRUE, TRUE, + FALSE, NULL, NULL, FALSE, 0, FALSE, req_id, "M", "maneuver-rules"); + decarta_geocode_free (start); + decarta_geocode_free (end); + data->route_cb = route_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_route, (gpointer)data); + } else if (0 == g_strcmp0("5x",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaAddress *start_addr = decarta_address_new ("US", "EN", TRUE, "1600 Amphitheatre Parkway, 94043", NULL); + DecartaAddress *end_addr = decarta_address_new ("US", "EN", TRUE, "4 North Second St, 95113", NULL); + DecartaGeocode *start = decarta_geocode_new (NULL, start_addr); + DecartaGeocode *end = decarta_geocode_new (NULL, end_addr); + decarta_address_free (start_addr); + decarta_address_free (end_addr); + guint req_id = 28; + data->route_request = decarta_route_request_new (DECARTA_ROUTE_PREF_FASTEST, start, end, NULL, TRUE, FALSE, + FALSE, NULL, NULL, FALSE, 0, FALSE, req_id, "M", "maneuver-rules"); + decarta_geocode_free (start); + decarta_geocode_free (end); + data->route_cb = route_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_route, (gpointer)data); + } else if (0 == g_strcmp0("5y",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaPosition *start_pos = decarta_position_new (37.336723, -121.889555); + DecartaPosition *end_pos = decarta_position_new (37.33461, -121.876445); + DecartaPosition *via_pos = decarta_position_new (37.329475, -121.891444); + DecartaGeocode *start = decarta_geocode_new (start_pos, NULL); + DecartaGeocode *end = decarta_geocode_new (end_pos, NULL); + GList *via_geocode_list = decarta_geocode_list_append (NULL, decarta_geocode_new (via_pos, NULL)); + decarta_position_free (start_pos); + decarta_position_free (end_pos); + decarta_position_free (via_pos); + guint req_id = 29; + data->route_request = decarta_route_request_new (DECARTA_ROUTE_PREF_FASTEST, start, end, via_geocode_list, FALSE, TRUE, + FALSE, NULL, NULL, FALSE, 0, FALSE, req_id, "M", "maneuver-rules"); + decarta_geocode_free (start); + decarta_geocode_free (end); + decarta_geocode_list_free (via_geocode_list); + data->route_cb = route_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_route, (gpointer)data); + } else if (0 == g_strcmp0("5z",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + DecartaAddress *start_addr = decarta_address_new ("US", "EN", TRUE, "1600 Amphitheatre Parkway, 94043", NULL); + DecartaPosition *end_pos = decarta_position_new (37.336850, -121.889591); + DecartaGeocode *start = decarta_geocode_new (NULL, start_addr); + DecartaGeocode *end = decarta_geocode_new (end_pos, NULL); + decarta_address_free (start_addr); + decarta_position_free (end_pos); + guint req_id = 30; + data->route_request = decarta_route_request_new (DECARTA_ROUTE_PREF_FASTEST, start, end, NULL, FALSE, FALSE, + FALSE, NULL, NULL, FALSE, 0, FALSE, req_id, "M", "maneuver-rules"); + decarta_geocode_free (start); + decarta_geocode_free (end); + data->route_cb = route_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_route, (gpointer)data); + } else if (0 == g_strcmp0("55",strOpt)) { + int req_id; + g_printf("Input ReqID : "); + scanf("%d", &req_id); + + decarta_search_route_async_cancel (req_id); + } else if (0 == g_strcmp0("6",strOpt)) { + DecartaPosition *pos = decarta_position_new (37.259133, 127.055031); + DecartaMap *map = NULL; + int err = decarta_search_map(pos, 15, &map); + decarta_position_free (pos); + if (DECARTA_ERROR_NONE == err) { + g_printf("Success\n"); + print_map (map); + decarta_map_free (map); + } else g_printf("Failed: %d\n", err); + } else if (0 == g_strcmp0("6a",strOpt)) { + IdleData* data= g_new0 (IdleData, 1); + data->pos = decarta_position_new (37.259133, 127.055031); + data->zoom = 15; + data->map_cb = map_cb; + data->user_data = NULL; + g_idle_add((GSourceFunc)idle_map, (gpointer)data); + } else if (0 == g_strcmp0("66",strOpt)) { + decarta_search_map_async_cancel (); + } else if (0 == g_strcmp0("0",strOpt)) { + g_main_loop_quit(g_mainloop); + break; + } + } + g_thread_join(g_main); + //net_close(); + _map_connect_destroy(); + g_printf("\n--- Exit Decarta Test App ---\n"); + return 1; +} + -- 2.7.4