Release Tizen2.0 beta
authorMinjune Kim <sena06.kim@samsung.com>
Tue, 21 Aug 2012 09:23:26 +0000 (18:23 +0900)
committerMinjune Kim <sena06.kim@samsung.com>
Tue, 21 Aug 2012 09:23:26 +0000 (18:23 +0900)
53 files changed:
LICENSE [new file with mode: 0755]
Makefile.am [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0755]
crypt/Makefile.am [new file with mode: 0644]
crypt/conf.org [new file with mode: 0644]
crypt/cryption.c [new file with mode: 0644]
crypt/cryption.h [new file with mode: 0644]
crypt/docrypt.c [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/elementary-decarta.install.in [new file with mode: 0644]
debian/libdecarta-dev.install.in [new file with mode: 0644]
debian/libdecarta.install.in [new file with mode: 0644]
debian/libdecarta.postinst [new file with mode: 0644]
debian/location-decarta.install.in [new file with mode: 0644]
debian/rules [new file with mode: 0755]
decarta.pc.in [new file with mode: 0644]
decarta/Makefile.am [new file with mode: 0644]
decarta/decarta.h [new file with mode: 0644]
decarta/decarta_config.c [new file with mode: 0755]
decarta/decarta_config.h [new file with mode: 0755]
decarta/decarta_directory.c [new file with mode: 0755]
decarta/decarta_directory.h [new file with mode: 0755]
decarta/decarta_geocode.c [new file with mode: 0644]
decarta/decarta_geocode.h [new file with mode: 0644]
decarta/decarta_log.h [new file with mode: 0644]
decarta/decarta_maps.c [new file with mode: 0755]
decarta/decarta_maps.h [new file with mode: 0644]
decarta/decarta_route.c [new file with mode: 0755]
decarta/decarta_route.h [new file with mode: 0755]
decarta/decarta_types.c [new file with mode: 0755]
decarta/decarta_types.h [new file with mode: 0755]
decarta/decarta_xml.h [new file with mode: 0755]
decarta/decarta_xml_directory.c [new file with mode: 0755]
decarta/decarta_xml_geocode.c [new file with mode: 0755]
decarta/decarta_xml_internal.c [new file with mode: 0755]
decarta/decarta_xml_internal.h [new file with mode: 0755]
decarta/decarta_xml_maps.c [new file with mode: 0755]
decarta/decarta_xml_route.c [new file with mode: 0755]
decarta/http_wrapper.c [new file with mode: 0755]
decarta/http_wrapper.h [new file with mode: 0644]
decarta/xml_wrapper.c [new file with mode: 0755]
decarta/xml_wrapper.h [new file with mode: 0755]
elm_module/Makefile.am [new file with mode: 0644]
elm_module/decarta.c [new file with mode: 0755]
location_module/Makefile.am [new file with mode: 0755]
location_module/location_decarta.c [new file with mode: 0755]
location_module/location_decarta.h [new file with mode: 0644]
packaging/libdecarta.spec [new file with mode: 0755]
tests/Makefile.am [new file with mode: 0644]
tests/decarta_test.c [new file with mode: 0755]

diff --git a/LICENSE b/LICENSE
new file mode 100755 (executable)
index 0000000..bbe9d02
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,206 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+\r
+\r
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..ef0197c
--- /dev/null
@@ -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 (executable)
index 0000000..e6f3a78
--- /dev/null
@@ -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 (executable)
index 0000000..d8e8535
--- /dev/null
@@ -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 (file)
index 0000000..12529a1
--- /dev/null
@@ -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 (file)
index 0000000..2eceb1d
--- /dev/null
@@ -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 (file)
index 0000000..16f8a28
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <gcrypt.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#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)<blocklen)? inbuf_len-idx : blocklen;
+               memset (inblock, 0, blocklen);
+               memset (outblock, 0, blocklen);
+        if(!memcpy(inblock, inbuf+idx, len)) {
+               ret = FALSE;
+               break;
+        }
+
+        if (is_encrypt) err = gcry_cipher_encrypt (hd, outblock, blocklen, inblock, blocklen);
+               else            err = gcry_cipher_decrypt (hd, outblock, blocklen, inblock, blocklen);
+               if (err) {
+                       g_warning ("fail to gcry_cipher_encrypt or gcry_cipher_decrypt: %s\n", gpg_strerror (err));
+                       ret = FALSE;
+                       break;
+               }
+               if(!memcpy(outbuf+idx, outblock, blocklen)) {
+               ret = FALSE;
+               break;
+        }
+           idx += blocklen;
+       }
+       *outbuf_len = idx;
+
+       gcry_cipher_close (hd);
+       gcry_free (inblock);
+       gcry_free (outblock);
+       return ret;
+}
+
+gboolean
+do_encryption (const char *filename)
+{
+       g_return_val_if_fail (filename, FALSE);
+
+       gboolean ret = TRUE;
+       void *keybuf = NULL;
+       char inbuf[BUF_LEN];
+       char outbuf[BUF_LEN];
+       size_t key_buflen;
+       size_t inlen = 0;
+       size_t outlen = 0;
+       int infd = -1;
+       int outfd = -1;
+       char* outfile = g_strdup_printf("%s.enc", filename);
+
+       memset (inbuf, 0, BUF_LEN);
+       memset (outbuf, 0, BUF_LEN);
+
+       if ((outfd = open(outfile, O_WRONLY|O_CREAT, 0664)) < 0) {
+               g_warning ("open(%s) failed", outfile);
+               ret = FALSE;
+       } else {
+               if ((infd = open(filename, O_RDONLY)) < 0) {
+                       g_warning ("open(%s) failed", filename);
+                       ret = FALSE;
+               } else {
+                       if ((inlen = read(infd, inbuf, BUF_LEN)) <= 0) {
+                               g_warning ("read(%d) failed", infd);
+                               ret = FALSE;
+                       }
+               }
+       }
+       
+       if (ret != FALSE && (keybuf = string2hex (key_string, &key_buflen)) && inbuf != NULL) {
+               if (!encrypt_decrypt (TRUE, NULL, 0, keybuf, key_buflen, (void*)inbuf, inlen, (void*)outbuf, &outlen)) {
+                       g_warning ("encrypt_decrypt failed");
+                       ret = FALSE;
+               } else {
+                       if (write(outfd, outbuf, outlen) < 0) {
+                               g_warning ("write(%d) failed", outfd);
+                               ret = FALSE;
+                       }
+               }
+       } else {
+               g_warning ("string2hex failed");
+               ret = FALSE;
+       }
+       
+       g_free (outfile);
+       if (keybuf) gcry_free (keybuf);
+       if (outfd >= 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 (file)
index 0000000..0fd8e17
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 (file)
index 0000000..ee1c9cd
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <glib/gprintf.h>
+#include <stdio.h>
+#include <string.h>
+#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 (file)
index 0000000..ad727a4
--- /dev/null
@@ -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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  Thu, 09 Aug 2012 20:16:12 +0900
+
+libdecarta (0.2.7-15) unstable; urgency=low
+
+  * [Bug]<WEB-1361> multi geocoder crash. postion_cb()'s accuracy should be copied before append
+  * Tag: libdecarta_0.2.7-15
+
+ -- Minjune Kim <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <youngae.kang@samsung.com>  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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <youngae.kang@samsung.com>  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 <daejins.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <daejins.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <sena06.kim@samsung.com>  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 <yhan.kim@samsung.com>  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 <yhan.kim@samsung.com>  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 <yhan.kim@samsung.com>  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 <yhan.kim@samsung.com>  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 <yhan.kim@samsung.com>  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 <yhan.kim@samsung.com>  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 <daejins.kim@samsung.com>  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 <daejins.kim@samsung.com>  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 <daejins.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <the81.kim@samsung.com>  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 <sangho.g.park@samsung.com>  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 <the81.kim@samsung.com>  Mon, 30 Aug 2010 12:01:05 +0900
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..022315c
--- /dev/null
@@ -0,0 +1,42 @@
+Source: libdecarta
+Section: libs
+Priority: extra
+Maintainer: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>, Genie kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>, Ming Zhu <mingwu.zhu@samsung.com>
+Uploaders: Yunhan Kim <yhan.kim@samsung.com>
+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 (file)
index 0000000..88d26f0
--- /dev/null
@@ -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 (file)
index 0000000..d59062e
--- /dev/null
@@ -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 (file)
index 0000000..7b47e5d
--- /dev/null
@@ -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 (file)
index 0000000..4575c2f
--- /dev/null
@@ -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 (file)
index 0000000..f99d979
--- /dev/null
@@ -0,0 +1 @@
+@PREFIX@/lib/location/module/*.so*
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..a48dfca
--- /dev/null
@@ -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 (file)
index 0000000..d585588
--- /dev/null
@@ -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 (file)
index 0000000..8a0f60f
--- /dev/null
@@ -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 (file)
index 0000000..ef8d4df
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <decarta_types.h>
+#include <decarta_geocode.h>
+#include <decarta_directory.h>
+#include <decarta_route.h>
+#include <decarta_maps.h>
+
+#endif
diff --git a/decarta/decarta_config.c b/decarta/decarta_config.c
new file mode 100755 (executable)
index 0000000..d5fe5c2
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#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 (executable)
index 0000000..9ced908
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+
+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 (executable)
index 0000000..9c15433
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <stdbool.h>
+#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 (executable)
index 0000000..59317bc
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <decarta_types.h>
+
+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 (file)
index 0000000..a073b57
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+
+#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 (file)
index 0000000..8fb490b
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <decarta_types.h>
+
+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 (file)
index 0000000..dcb8f03
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <dlog.h>
+#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 <dlog.h>
+#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 (executable)
index 0000000..abcc14a
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <stdbool.h>
+#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 (file)
index 0000000..8a06315
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <decarta_types.h>
+
+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 (executable)
index 0000000..5b1a754
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <stdbool.h>
+#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 (executable)
index 0000000..56b7a1c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <decarta_types.h>
+
+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 (executable)
index 0000000..c358c94
--- /dev/null
@@ -0,0 +1,947 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <decarta_types.h>
+
+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 (executable)
index 0000000..598f602
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+
+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 (executable)
index 0000000..d034440
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+
+#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 (executable)
index 0000000..871cdf7
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#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 (executable)
index 0000000..2365345
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#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 (executable)
index 0000000..057ae30
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#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 (executable)
index 0000000..a00978a
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#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 (executable)
index 0000000..6f59633
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#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 (executable)
index 0000000..3c276c3
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#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 (executable)
index 0000000..973a2d9
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <gconf/gconf-client.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libsoup/soup.h>
+
+#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 (file)
index 0000000..87e3e90
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+
+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 (executable)
index 0000000..97699fb
--- /dev/null
@@ -0,0 +1,1944 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/globals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/tree.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlmemory.h>
+
+#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;(i<len) && (i < 30);i++) {
+               output[i] = ch[i];
+       }
+       output[i] = 0;
+       DECARTA_LOGD( "SAX.ignorableWhitespace(%s, %d)\n", output, len);
+}
+
+/**
+ * __sax_processing_instruction_cb:
+ * @ctxt:  An XML parser context
+ * @target:  the target name
+ * @data: the PI data's
+ * @len: the number of xmlChar
+ *
+ * A processing instruction has been parsed.
+ */
+static void
+__sax_processing_instruction_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
+                      const xmlChar *data)
+{
+
+       if (!target) {
+               DECARTA_LOGD("[ERROR] target is NULL\n");
+               return;
+       }
+       if (data != NULL) {
+               DECARTA_LOGD( "SAX.processingInstruction(%s, %s)\n",
+                       (char *) target, (char *) data);
+       } else {
+               DECARTA_LOGD( "SAX.processingInstruction(%s, NULL)\n",
+                       (char *) target);
+       }
+}
+
+/**
+ * __sax_comment_cb:
+ * @ctxt:  An XML parser context
+ * @value:  the comment content
+ *
+ * A comment has been parsed.
+ */
+static void
+__sax_comment_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
+{
+       if (!value) {
+               DECARTA_LOGD("[ERROR] value is NULL\n");
+               return;
+       }
+
+       DECARTA_LOGD( "SAX.comment(%s)\n", value);
+}
+
+/**
+ * __sax_warning_cb:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a warning messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+__sax_warning_cb(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+       va_list args;
+
+       va_start(args, msg);
+       DECARTA_LOGD( "SAX.warning: ");
+       vfprintf(stdout, msg, args);
+       va_end(args);
+}
+
+/**
+ * __sax_error_cb:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a error messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+__sax_error_cb(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+       va_list args;
+
+       va_start(args, msg);
+       DECARTA_LOGD( "SAX.error: ");
+       vfprintf(stdout, msg, args);
+       va_end(args);
+}
+
+/**
+ * __sax_fatal_error_cb:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a fatalError messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+__sax_fatal_error_cb(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+{
+       va_list args;
+
+       va_start(args, msg);
+       DECARTA_LOGD( "SAX.fatalError: ");
+       vfprintf(stdout, msg, args);
+       va_end(args);
+}
+
+/**
+ * __sax_get_parameter_entity_cb:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlParserInputPtr
+ */
+static xmlEntityPtr
+__sax_get_parameter_entity_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+{
+       if (!name) {
+               DECARTA_LOGD("[ERROR] name is NULL\n");
+               return(NULL);
+       }
+
+       DECARTA_LOGD( "SAX.getParameterEntity(%s)\n", name);
+       return(NULL);
+}
+
+/**
+ * __sax_cdata_block_cb:
+ * @ctx: the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+static void
+__sax_cdata_block_cb(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
+{
+
+       if (!value) {
+               DECARTA_LOGD("[ERROR] value is NULL\n");
+               return;
+       }
+       DECARTA_LOGD( "SAX.pcdata(%.20s, %d)\n",
+               (char *) value, len);
+}
+
+/**
+ * __sax_external_subset_cb:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ */
+static void
+__sax_external_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.externalSubset(%s,", name);
+       if (ExternalID == NULL) {
+               DECARTA_LOGD( " ,");
+       } else {
+               DECARTA_LOGD( " %s,", ExternalID);
+       }
+       if (SystemID == NULL) {
+               DECARTA_LOGD( " )\n");
+       } else {
+               DECARTA_LOGD( " %s)\n", SystemID);
+       }
+}
+
+/*
+ * SAX2 specific callbacks
+ */
+/**
+ * __sax_start_element_ns_cb:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+__sax_start_element_ns_cb(void *ctx,
+                    const xmlChar *localname,
+                    const xmlChar *prefix,
+                    const xmlChar *URI,
+                   int nb_namespaces,
+                   const xmlChar **namespaces,
+                   int nb_attributes,
+                   int nb_defaulted,
+                   const xmlChar **attributes)
+{
+       if (!ctx || !localname) {
+               DECARTA_LOGD("[ERROR] ctx or localname is NULL\n");
+               return;
+       }
+
+       DECARTA_LOGD( "SAX.startElementNs(%s)", (char *) localname);
+       int i = 0;
+       int j = 0;
+       sax_route_data_s *route_data = (sax_route_data_s *)ctx;
+
+       if (!g_strcmp0("Error", (char *) localname)) {
+               DECARTA_LOGD("Response Error!");
+               route_data->has_error = 1;
+               /** <ns1:Error severity="Error" message="not implemented" errorCode="NotSupported"/> */
+               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 <Point> 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");
+                                               /** <xls:RouteMap description="Route Overview"> */
+                                               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);
+                       /** <xls:RouteInstruction description="route maneuver 1" duration="PT0H0M0S" tour="0"> */
+                       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) {
+                       /** <xls:distance value="0.00"/> */
+                       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 <distance>: 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 <distance>: 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 (executable)
index 0000000..44c74aa
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+
+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 (file)
index 0000000..d402a87
--- /dev/null
@@ -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 (executable)
index 0000000..4aface8
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <Elementary.h>
+#include <Eina.h>
+#include <glib.h>
+#include <math.h>
+
+#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 (executable)
index 0000000..15c1146
--- /dev/null
@@ -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 (executable)
index 0000000..88f0316
--- /dev/null
@@ -0,0 +1,1740 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <glib/gprintf.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <vconf.h>
+#include <location-module.h>
+#include <location-poi.h>
+#include <decarta.h>
+#include <decarta_log.h>
+#include <location.h>
+#include <location-map-service.h>
+#include <location-map-service-ext.h>
+#include <decarta_config.h>
+
+#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 (file)
index 0000000..4b7414c
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <location-types.h>
+
+#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 (executable)
index 0000000..0c0fa06
--- /dev/null
@@ -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 (file)
index 0000000..c27aa33
--- /dev/null
@@ -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 (executable)
index 0000000..67b129b
--- /dev/null
@@ -0,0 +1,967 @@
+/*
+ * libdecarta
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
+ *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ *
+ * 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 <glib.h>
+#include <glib/gprintf.h>
+#include <network/net_connection.h>
+#include <unistd.h>
+#include <gconf/gconf-client.h>
+#include <decarta.h>
+
+#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 &amp; 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 &amp; 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 &amp; 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 &amp; 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;
+}
+