From: Kibum Kim Date: Mon, 27 Feb 2012 12:16:21 +0000 (+0900) Subject: tizen beta release X-Git-Tag: 2.0_release~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bf38419bfe5400082f5804438e61b3ce60e64e4e;p=platform%2Fcore%2Fpim%2Fcalendar-service.git tizen beta release --- bf38419bfe5400082f5804438e61b3ce60e64e4e diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..93cf8d0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,64 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(calendar-service C) + +#IF("${CMAKE_BUILD_TYPE}" STREQUAL "") +# SET(CMAKE_BUILD_TYPE "Release") +#ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") +#MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") + +SET(DEST_INCLUDE_DIR "include/calendar-svc") +SET(SRC_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include") + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/${DEST_INCLUDE_DIR}") +SET(VERSION_MAJOR 0) +SET(VERSION "${VERSION_MAJOR}.1.12") + +#INCLUDE_DIRECTORIES(${SRC_INCLUDE_DIR}) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -I${CMAKE_SOURCE_DIR}/include") + +FILE(GLOB SRCS src/*.c) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED glib-2.0 sqlite3 vconf dlog db-util alarm-service) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +#SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +#SET(CMAKE_C_FLAGS_RELEASE "-mabi=aapcs-linux -march=armv7-a -msoft-float -O2") + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS}) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc;schema/schema.h") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) +INSTALL(FILES ${PROJECT_NAME}.pc DESTINATION lib/pkgconfig) + +FILE(GLOB HEADER_FILES ${SRC_INCLUDE_DIR}/calendar-svc*.h) +INSTALL(FILES ${HEADER_FILES} DESTINATION ${DEST_INCLUDE_DIR}) + +FILE(GLOB NOTI_FILES ${CMAKE_SOURCE_DIR}/.CALENDAR_SVC_*_CHANGED) +INSTALL(FILES ${NOTI_FILES} DESTINATION /opt/data/calendar-svc) + +# for immigration +SET(IMMIGRATION "calendar") +SET(OLD_DEST_INCLUDE_DIR "include/calendar") +INSTALL(FILES ${IMMIGRATION}.pc DESTINATION lib/pkgconfig) +INSTALL(FILES ${SRC_INCLUDE_DIR}/calendar-svc-provider.h DESTINATION ${OLD_DEST_INCLUDE_DIR}) +INSTALL(FILES ${SRC_INCLUDE_DIR}/calendar-svc-struct.h DESTINATION ${OLD_DEST_INCLUDE_DIR}) +INSTALL(FILES ${SRC_INCLUDE_DIR}/calendar-svc-errors.h DESTINATION ${OLD_DEST_INCLUDE_DIR}) + +ADD_SUBDIRECTORY(schema) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bae7f54 --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..4c49449 --- /dev/null +++ b/NOTICE @@ -0,0 +1 @@ +Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. diff --git a/calendar-service.pc.in b/calendar-service.pc.in new file mode 100755 index 0000000..afff9e8 --- /dev/null +++ b/calendar-service.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: @PROJECT_NAME@ +Description: @PROJECT_NAME@ library +Version: @VERSION@ +Requires: glib-2.0 alarm-service +Libs: -L${libdir} -l@PROJECT_NAME@ +Cflags: -I${includedir} diff --git a/calendar.pc b/calendar.pc new file mode 100755 index 0000000..2b4d600 --- /dev/null +++ b/calendar.pc @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include/calendar-svc + +Name: calendar-service +Description: calendar-service library +Version: 0.1.8 +Requires: glib-2.0 alarm-service +Libs: -L${libdir} -lcalendar-service +Cflags: -I${includedir} diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..7380383 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,7 @@ +libslp-calendar (0.1.12-15) unstable; urgency=low + + * release + * Git: pkgs/l/libslp-calendar + * Tag: libslp-calendar_0.1.12-15 + + -- Youngjae Shin Wed, 01 Feb 2012 10:16:13 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..04272ad --- /dev/null +++ b/debian/control @@ -0,0 +1,25 @@ +Source: libslp-calendar +Section: devel +Priority: extra +Maintainer: Youngjae Shin , Sunghyuk Lee , Jeesun Kim +Build-Depends: debhelper (>= 5), libslp-db-util-dev, libsqlite3-dev, libglib2.0-dev, dlog-dev, libvconf-dev, libvconf-keys-dev, libalarm-dev +Standards-Version: 3.7.2 + +Package: libslp-calendar-dev +Section: devel +Architecture: any +Depends: libslp-calendar-0 (= ${Source-Version}), libglib2.0-dev, libalarm-dev +Description: calendar service Library (development) + +Package: libslp-calendar-0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: calendar service Library (Library) + +Package: libslp-calendar-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libslp-calendar-0 (= ${Source-Version}) +Description: calendar service Library (unstripped) + diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..4f93c69 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,7 @@ +Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + +This program is free software; you can redistribute it and/or modify +it under the terms of the Apache License version 2.0. + +The full text of the Apache 2.0 can be found in +/usr/share/common-licenses. diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..ca882bb --- /dev/null +++ b/debian/dirs @@ -0,0 +1,2 @@ +usr/bin +usr/sbin diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..a0f0008 --- /dev/null +++ b/debian/docs @@ -0,0 +1 @@ +CMakeLists.txt diff --git a/debian/libslp-calendar-0.install.in b/debian/libslp-calendar-0.install.in new file mode 100644 index 0000000..f5ec216 --- /dev/null +++ b/debian/libslp-calendar-0.install.in @@ -0,0 +1,3 @@ +@PREFIX@/lib/*.so.* +@PREFIX@/bin/calendar-svc-initdb +/opt/* diff --git a/debian/libslp-calendar-0.postinst b/debian/libslp-calendar-0.postinst new file mode 100644 index 0000000..825430b --- /dev/null +++ b/debian/libslp-calendar-0.postinst @@ -0,0 +1,22 @@ +#!/bin/sh + +if [ ! -d /opt/dbspace ] +then + mkdir -p /opt/dbspace +fi + +calendar-svc-initdb + +if [ "$USER" = "root" ] +then + chown root:root /usr/lib/libcalendar-service.so.* + chown :6003 /opt/data/calendar-svc/.CALENDAR_SVC_* + chown :6003 /opt/dbspace/.calendar-svc.db + chown :6003 /opt/dbspace/.calendar-svc.db-journal +fi + +chmod 660 /opt/dbspace/.calendar-svc.db +chmod 660 /opt/dbspace/.calendar-svc.db-journal +chmod 660 /opt/data/calendar-svc/.CALENDAR_SVC_* + +echo "Done" diff --git a/debian/libslp-calendar-dev.install.in b/debian/libslp-calendar-dev.install.in new file mode 100644 index 0000000..690c8d5 --- /dev/null +++ b/debian/libslp-calendar-dev.install.in @@ -0,0 +1,5 @@ +@PREFIX@/lib/*.so +@PREFIX@/include/calendar-svc/*.h +@PREFIX@/include/calendar/*.h +@PREFIX@/lib/pkgconfig/calendar-service.pc +@PREFIX@/lib/pkgconfig/calendar.pc diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..eefc51d --- /dev/null +++ b/debian/rules @@ -0,0 +1,112 @@ +#!/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 + +CFLAGS += -Wall +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +LDFLAGS += -Wl,--hash-style=both -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX) + + 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}; \ + 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 + rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake Makefile install_manifest.txt + cd schema; rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake Makefile install_manifest.txt + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_prep + dh_installdirs + + # Add here commands to install the package. + $(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 --dbg-package=libslp-calendar-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/include/calendar-svc-errors.h b/include/calendar-svc-errors.h new file mode 100755 index 0000000..1d7b29f --- /dev/null +++ b/include/calendar-svc-errors.h @@ -0,0 +1,67 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/** + * @defgroup return_value return_value + * @ingroup CALENDAR_SVC + * @brief + * return value with api call + */ + +#ifndef __CALENDAR_SVC_ERRORS_H__ +#define __CALENDAR_SVC_ERRORS_H__ + +typedef enum +{ + CAL_ERR_EVENT_START_DATE = -405, + CAL_ERR_EVENT_END_DATE = -404, + CAL_ERR_EVENT_REPEAT_END_DATE = -403, + CAL_ERR_EVENT_DURATION = -402, + CAL_ERR_EVENT_REPEAT_DURATION_TOO_SHORT = -401, + + CAL_ERR_INVALID_DATA_TYPE =-301, + + CAL_ERR_DB_LOCK = -204, + CAL_ERR_DB_RECORD_NOT_FOUND = -203, + CAL_ERR_DB_FAILED = -202, + CAL_ERR_DB_NOT_OPENED= -201, + + CAL_ERR_ALARMMGR_FAILED = -105, + CAL_ERR_TIME_FAILED = -104, + CAL_ERR_INOTIFY_FAILED = -103, + CAL_ERR_VCONF_FAILED = -102, + CAL_ERR_VOBJECT_FAILED = -101, + + CAL_ERR_NO_SPACE = -11, + CAL_ERR_IO_ERR = -10, + CAL_ERR_EXCEEDED_LIMIT = -9, + CAL_ERR_OUT_OF_MEMORY = -8, + CAL_ERR_ALREADY_EXIST = -7, + CAL_ERR_ENV_INVALID = -6, + CAL_ERR_ARG_NULL = -5, + CAL_ERR_ARG_INVALID = -4, + CAL_ERR_NO_DATA = -3, + CAL_ERR_FINISH_ITER= -2, + CAL_ERR_FAIL= -1, + CAL_SUCCESS = 0, + CAL_FALSE = 0, + CAL_TRUE +}cal_error; + +#endif /* __CALENDAR_SVC_ERRORS_H__ */ + diff --git a/include/calendar-svc-provider.h b/include/calendar-svc-provider.h new file mode 100755 index 0000000..2909301 --- /dev/null +++ b/include/calendar-svc-provider.h @@ -0,0 +1,2862 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_H__ +#define __CALENDAR_SVC_H__ + +/** + * @defgroup CALENDAR_SVC Calendar Service + */ + +/** + * @defgroup common common + * @ingroup CALENDAR_SVC + * @brief + * common struct for calendar service + */ + + +/** + * cal_struct is an opaque type, it must be + * used via accessor functions. + * @addtogroup common + * @see calendar_svc_struct_new(), calendar_svc_struct_free() + * @see calendar_svc_struct_get_value(), calendar_svc_struct_get_list(), + * @see calendar_svc_struct_store_value(), calendar_svc_struct_store_list() + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * @addtogroup common + * @{ + */ + +/** + * This enumeration defines schedule category. + */ +typedef enum +{ + CAL_SCH_NONE=0, /**< None type */ + CAL_SCH_APPOINTMENT, /**< appointment category */ + CAL_SCH_IMPORTANT, /**< important category */ + CAL_SCH_SPECIAL_OCCASION, /**< anniversary category */ + CAL_SCH_BIRTHDAY, /**< birthday category */ + CAL_SCH_HOLIDAY, /**< holiday category */ + CAL_SCH_PRIVATE, /**< private category */ + CAL_SCH_BUSSINESS, /**< bussiness category */ +} cal_sch_category_t; + +/** + * This enumeration date type, sun or lunar. + */ +typedef enum +{ + CAL_DATE_SUN = 0, /**< date is sun type*/ + CAL_DATE_LUNAR, /**< date is lunar type */ +} cal_date_type_t; + +/** + * This enumeration defines Remind Tick Unit for schedule. + * Ex. remindTick = 1, remindTickUnit = CAL_SCH_TIME_UNIT_MIN, Organizer alarms + * 1 minute before schedule starting time. + */ +typedef enum +{ + CAL_SCH_TIME_UNIT_OFF = -1, /**< off */ + CAL_SCH_TIME_UNIT_MIN = 0, /**< Minute */ + CAL_SCH_TIME_UNIT_HOUR, /**< Hour */ + CAL_SCH_TIME_UNIT_DAY, /**< Day */ + CAL_SCH_TIME_UNIT_WEEK, /**< Week */ + CAL_SCH_TIME_UNIT_MONTH, /**< Month - will be removed*/ + CAL_SCH_TIME_UNIT_SPECIFIC /**< using alarm time */ +} cal_sch_remind_tick_unit_t; + +/** + * This enumeration defines Repeat term. + */ +typedef enum +{ + CAL_REPEAT_NONE = 0, /**< never Repeat */ + CAL_REPEAT_EVERY_DAY, /**< Repeats every day */ + CAL_REPEAT_EVERY_WEEK, /**< Repeats every week */ + CAL_REPEAT_EVERY_MONTH, /**< Repeats every month */ + CAL_REPEAT_EVERY_YEAR, /**< Repeats every year */ + CAL_REPEAT_EVERY_WEEKDAYS, /**< Repeats every weekdays *//* same with CAL_REPEAT_EVERY_WEEK, but week_flag="0111110", day_date=1, sun_moon=0, week_start=0 */ + CAL_REPEAT_EVERY_MONTH_DAY, /**< Repeats every month's week days *//* same with CAL_REPEAT_EVERY_MONTH, but week_flag="1000000"~"0000001", day_date=0, sun_moon=0, week_start=0 */ + CAL_REPEAT_EVERY_YEAR_DAY, /**< Repeats every year's month week days *//* same with CAL_REPEAT_EVERY_YEAR, but week_flag="1000000"~"0000001", day_date=0, sun_moon=0, week_start=0 */ +} cal_repeat_term_t; + +/** + * This enumeration defines sync status. + */ +typedef enum +{ + CAL_SYNC_STATUS_NEW = 0, /**< newly added. */ + CAL_SYNC_STATUS_UPDATED, /**< updated. */ + CAL_SYNC_STATUS_DELETED, /**< deleted. */ + CAL_SYNC_STATUS_SYNCED, /**< synced */ +} cal_sync_status_t; + +/** + * This enumeration defines Expiration for schedule data. + */ +typedef enum +{ + CAL_SCH_EXPIRATION_NONE = 0, /**< never expirate */ + CAL_SCH_EXPIRATION_AFTER_1_MONTH, /**< After 1 month */ + CAL_SCH_EXPIRATION_AFTER_1_YEAR, /**< After 1 year */ + CAL_SCH_EXPIRATION_AFTER_2_YEARS, /**< After 2 years */ + CAL_SCH_EXPIRATION_AFTER_3_YEARS /**< After 3 years */ +} cal_expiration_t; + +/** + * This enumeration defines lart type. + */ +typedef enum +{ + CAL_ALERT_MELODY = 0, /**< alarm type is melody */ + CAL_ALERT_MUTE, /**< alarm type is mute */ + CAL_ALERT_INCREASING_MELODY, /**< alarm type is increasing melody */ + CAL_ALERT_VIBRATION, /**< alarm type is vibrate */ + CAL_ALERT_VIBRATION_THEN_MELODY, /**< alarm type is vibrate then melody */ + CAL_ALERT_VIBMELODY, /**< alarm type is melody with vibrate */ + CAL_ALERT_VIB_INCREASING_MELODY /**< alarm type is increasing melody */ +} cal_alert_type_t; + +/** + * This enumeration defines alarm volume . + */ +typedef enum +{ + CAL_SNOOZE_OFF = 0, /**< snoooze is off */ + CAL_SNOOZE_1MIN, /**< snoooze time is 1 min */ + CAL_SNOOZE_3MINS, /**< snoooze time is 3 mins */ + CAL_SNOOZE_5MINS, /**< snoooze time is 5 mins */ + CAL_SNOOZE_10MINS, /**< snoooze time is 10 mins */ + CAL_SNOOZE_15MINS /**< snoooze time is 15 mins */ + +} cal_snooze_type_t; + +/** + * This enumeration defines alarm snooze count . + */ +typedef enum +{ + CAL_SNOOZE_0TIME = 0, /**< snoooze count is 0 time */ + CAL_SNOOZE_1TIME = 1, /**< snoooze count is 1 time */ + CAL_SNOOZE_2TIMES = 2, /**< snoooze count is 2 times */ + CAL_SNOOZE_5TIMES = 5, /**< snoooze count is 5 times */ + CAL_SNOOZE_10TIMES = 10 /**< snoooze count is 10 times */ +} cal_snooze_count_t; + +/** + * This enumeration defines attendee's status . + */ +typedef enum +{ + CAL_TZ_FLAG_GMT = 0, /**< gmt time */ + CAL_TZ_FLAG_LOCAL = 1, /**< calendar local time */ +} cal_timezone_flag; + +/** + * This enumeration defines calendar's visibility . + */ +typedef enum +{ + PUBLIC_VISIBILITY = 0, + PRIVATE_VISIBILITY, + CONFIDENTIAL_VISIBILITY +} cal_visibility_type_t; + +/** + * This enumeration defines event attendee's availability . + */ +typedef enum +{ + EVENT_BUSY_FB=0, + EVENT_BUSY_UNAVAILABLE_FB, + EVENT_FREE_FB, + EVENT_BUSY_TENTATIVE_FB, +} cal_event_availability_type_t; + + +/** + * This enumeration defines event attendee's role . + */ +typedef enum +{ + EVENT_ATTENDEE_REQ_PARTICIPANT_ROLE=0, + EVENT_ATTENDEE_OPT_PARTICIPANT_ROLE, + EVENT_ATTENDEE_NON_PARTICIPANT_ROLE, + EVENT_ATTENDEE_CHAIR_ROLE, +} cal_event_attendee_role_type_t; + +/** + * This enumeration defines event attendee's status. + */ +typedef enum +{ + EVENT_ATTENDEE_NEEDS_ACTION_AT_STATUS=0, + EVENT_ATTENDEE_ACCEPTED_AT_STATUS, + EVENT_ATTENDEE_DECLINED_AT_STATUS, + EVENT_ATTENDEE_TENTATIVE_AT_STATUS, + EVENT_ATTENDEE_DELEGATED_AT_STATUS, + EVENT_ATTENDEE_COMPLETED_AT_STATUS, + EVENT_ATTENDEE_IN_PROCESS_AT_STATUS +} cal_event_attendee_status_type_t; + + +/** + * This enumeration defines event attendee's type . + */ +typedef enum +{ + EVENT_ATTENDEE_INDIVIDUAL_TYPE=0, + EVENT_ATTENDEE_GROUP_TYPE, + EVENT_ATTENDEE_RESOURCE_TYPE, + EVENT_ATTENDEE_ROOM_TYPE, + EVENT_ATTENDEE_UNKNOWN_TYPE +} cal_event_attendee_type_t; + + +/** + * This enumeration defines CAL_VALUE_INT_PRIORITY . + */ +typedef enum +{ + EVENT_PRIORITY_LOW =0, + EVENT_PRIORITY_NORMAL, + EVENT_PRIORITY_HIGH, +} cal_priority_type_t; + +/** + * This enumeration defines status. + * (related with CAL_VALUE_INT_TASK_STATUS) + */ +typedef enum +{ + CALS_STATUS_NONE =0, + CALS_EVENT_STATUS_TENTATIVE, + CALS_EVENT_STATUS_CONFIRMED, + CALS_EVENT_STATUS_CANCELLED, + CALS_TODO_STATUS_NEEDS_ACTION, + CALS_TODO_STATUS_COMPLETED, + CALS_TODO_STATUS_IN_PROCESS, + CALS_TODO_STATUS_CANCELLED, +} cals_status_t; + +/** + * This enumeration defines calendar type. + * (related with CAL_TABLE_INT_STORE_TYPE) + */ +typedef enum +{ + CALS_CALENDAR_TYPE_NONE = 0, + CALS_CALENDAR_TYPE_EVENT = 1<<0, + CALS_CALENDAR_TYPE_TODO = 1<<1, +} cals_calendar_store_type; + +/** + * @} + */ + +/** + * @addtogroup common + * @{ + * brief + * calendar_svc_struct_new's argument + */ +#define CAL_STRUCT_TYPE /**< CAL_STRUCT_TYPE */ +#define CAL_STRUCT_CALENDAR "calendar" /**< CAL_STRUCT_CALENDAR */ +#define CAL_STRUCT_SCHEDULE "schedule" /**< CAL_STRUCT_SCHEDULE */ +#define CAL_STRUCT_TODO "todo" /**< CAL_STRUCT_TASK */ +#define CAL_STRUCT_TIMEZONE "timezone" /**< CAL_STRUCT_TIMEZONE */ + +// id for all data read +#define ALL_ACCOUNT_ID 0 +#define ALL_CALENDAR_ID 0 + +// id for all data without visibility false +#define ALL_VISIBILITY_ACCOUNT -2 + +// id for local data read +#define LOCAL_ACCOUNT_ID -1 +#define LOCAL_ALL_CALENDAR -1 + +#define DEFAULT_CALENDAR_ID 1 + +/** + * @} + */ + +/** + * @addtogroup common + * @{ + * brief + * calendar_svc_value_xxx()'s argument + */ +#define CAL_TABLE_INT_INDEX "index" +#define CAL_TABLE_TXT_CALENDAR_ID "calendar_id" +#define CAL_TABLE_TXT_UID "uid" +#define CAL_TABLE_TXT_LINK "link" +#define CAL_TABLE_INT_UPDATED "updated" +#define CAL_TABLE_TXT_NAME "name" +#define CAL_TABLE_TXT_DESCRIPTION "description" +#define CAL_TABLE_TXT_AUTHOR "author" +#define CAL_TABLE_TXT_COLOR "color" +#define CAL_TABLE_INT_HIDDEN "hidden" +#define CAL_TABLE_INT_SELECTED "selected" +#define CAL_TABLE_TXT_LOCATION "location" +#define CAL_TABLE_INT_LOCALE "locale" +#define CAL_TABLE_INT_COUNTRY "country" +#define CAL_TABLE_INT_TIME_ZONE "time_zone" +#define CAL_TABLE_TXT_TIME_ZONE_LABEL "timezone_label" +#define CAL_TABLE_INT_DISPLAY_ALL_TIMEZONES "display_all_timezones" +#define CAL_TABLE_INT_DATE_FIELD_ORDER "date_field_order" +#define CAL_TABLE_INT_FROMAT_24HOUR_TIME "format_24hour_time" +#define CAL_TABLE_INT_WEEK_START "week_start" +#define CAL_TABLE_INT_DEFAULT_CAL_MODE "default_cal_mode" +#define CAL_TABLE_INT_CUSTOM_CAL_MODE "custom_cal_mode" +#define CAL_TABLE_TXT_USER_LOCATION "user_location" +#define CAL_TABLE_TXT_WEATHER "weather" +#define CAL_TABLE_INT_SHOW_DECLINED_EVENTS "show_declined_events" +#define CAL_TABLE_INT_HIDE_INVITATIONS "hide_invitations" +#define CAL_TABLE_INT_ALTERNATE_CALENDAR "alternate_calendar" +#define CAL_TABLE_INT_VISIBILITY "visibility" +#define CAL_TABLE_INT_PROJECTION "projection" +#define CAL_TABLE_INT_SEQUENCE "sequence" +#define CAL_TABLE_INT_SUPRESS_REPLY_NOTIFICATIONS "suppress_reply_notifications" +#define CAL_TABLE_INT_SYNC_EVENT "sync_event" +#define CAL_TABLE_INT_TIMES_CLEANED "times_cleaned" +#define CAL_TABLE_INT_GUESTS_CAN_MODIFY "guests_can_modify" +#define CAL_TABLE_INT_GUESTS_CAN_INVITE_OTHERS "guests_can_invite_others" +#define CAL_TABLE_INT_GUESTS_CAN_SEE_GUESTS "guests_can_see_guests" +#define CAL_TABLE_INT_ACCESS_LEVEL "access_level" +#define CAL_TABLE_INT_SYNC_STATUS "sync_status" +#define CAL_TABLE_INT_IS_DELETED "is_deleted" +#define CAL_TABLE_INT_ACCOUNT_ID "account_id" +#define CAL_TABLE_INT_SENSITIVITY "sensitivity" +#define CAL_TABLE_INT_STORE_TYPE "store_type" /**< #cals_calendar_store_type */ + +/** + * @} + */ + +/** + * @addtogroup common + * @{ + * brief + * calendar_svc_value_xxx()'s argument + */ +#define CAL_VALUE_INT_INDEX "id" /**< Record index */ +#define CAL_VALUE_INT_ACCOUNT_ID "account_id" /**< account id */ +#define CAL_VALUE_INT_TYPE "type" /**< Calendar component type */ +#define CAL_VALUE_INT_CATEGORY "category" /**< Category of schedule #cal_sch_category_t */ +#define CAL_VALUE_TXT_SUMMARY "summary" /**< Summary, appointment, task: subject, birthday:Name */ +#define CAL_VALUE_TXT_DESCRIPTION "description" /**< Description,appointment, task: description, anniversary,holiday:occasion*/ +#define CAL_VALUE_TXT_LOCATION "location" /**< Location */ +#define CAL_VALUE_INT_ALL_DAY_EVENT "all_day_event" /**< All day event flag */ +#define CAL_VALUE_GMT_START_DATE_TIME "start_date_time" /**< schedule:start time, anniv,holiday,birthday,memo,todo: date */ +#define CAL_VALUE_GMT_END_DATE_TIME "end_date_time" /**< end time */ +#define CAL_VALUE_INT_REPEAT_TERM "repeat_item" /**< Repeat term */ +#define CAL_VALUE_INT_REPEAT_INTERVAL "repeat_interval" /**< Interval of repeat term */ +#define CAL_VALUE_INT_REPEAT_OCCURRENCES "repeat_occurrences" /**< occurrences of repeat */ +#define CAL_VALUE_GMT_REPEAT_END_DATE "repeat_end_date" /**< End date for repeat */ +#define CAL_VALUE_INT_SUN_MOON "sun_moon" /**< Using sun or lunar calendar */ +#define CAL_VALUE_INT_WEEK_START "week_start" /**< Start day of a week */ +#define CAL_VALUE_TXT_WEEK_FLAG "week_flag" /**< 1001000(sun,wed) Indicate which day is select in a week */ +#define CAL_VALUE_INT_DAY_DATE "day_date" /**< 0- for weekday(sun,mon,etc.), 1- for specific day(1,2.. Etc) */ +#define CAL_VALUE_GMT_LAST_MODIFIED_TIME "last_modified_time" /**< for PC Sync */ +#define CAL_VALUE_INT_MISSED "missed" /**< Miss alarm flag */ +#define CAL_VALUE_INT_TASK_STATUS "task_status" /**< current task status #cals_status_t */ +#define CAL_VALUE_INT_PRIORITY "priority" /**< Priority */ +#define CAL_VALUE_INT_TIMEZONE "timezone" /**< deprecated - timezone of task */ +#define CAL_VALUE_INT_FILE_ID "file_id" /**< file id for attach or alarm tone*/ +#define CAL_VALUE_INT_CONTACT_ID "contact_id" /**< contact id for birthday in contact list */ +#define CAL_VALUE_INT_BUSY_STATUS "busy_status" /**< ACS, G : Flag of busy or not */ +#define CAL_VALUE_INT_SENSITIVITY "sensitivity" /**< ACS, G : The sensitivity of the task item (normal, presonal, private, confidential). */ +#define CAL_VALUE_TXT_UID "uid" /**< ACS, G : Unique ID of the meeting item */ +#define CAL_VALUE_INT_CALENDAR_TYPE "calendar_type" /**< ACS, G : Type(all,phone,google) of calendar */ +#define CAL_VALUE_TXT_ORGANIZER_NAME "organizer_name" /**< ACS, G : Name of organizer(author) */ +#define CAL_VALUE_TXT_ORGANIZER_EMAIL "organizer_email" /**< ACS, G : Email of organizer */ +#define CAL_VALUE_INT_MEETING_STATUS "meeting_status" /**< ACS, G : The status of the meeting. */ +#define CAL_VALUE_TXT_GCAL_ID "gcal_id" /**< G : Server id of calendar */ +#define CAL_VALUE_INT_DELETED "deleted" /**< G : Flag for deleted */ +#define CAL_VALUE_TXT_UPDATED "updated" /**< G : Updated time stamp */ +#define CAL_VALUE_INT_LOCATION_TYPE "location_type" /**< G : Location type */ +#define CAL_VALUE_TXT_LOCATION_SUMMARY "location_summary" /**< G : A simple string value that can be used as a representation of this location */ +#define CAL_VALUE_TXT_ETAG "etag" /**< G : ETAG of this event */ +#define CAL_VALUE_INT_CALENDAR_ID "calendar_id" /**< G : id to map from calendar table */ +#define CAL_VALUE_INT_SYNC_STATUS "sync_status" /**< G : Indication for event entry whether added/ modified/ deleted */ +#define CAL_VALUE_TXT_EDIT_URL "edit_uri" /**< G : EditUri for google calendar */ +#define CAL_VALUE_TXT_GEDERID "gevent_id" /**< G : Server id of an event */ +#define CAL_VALUE_INT_DST "dst" /**< dst of event */ +#define CAL_VALUE_INT_ORIGINAL_EVENT_ID "original_event_id" /**< original event id for recurrency exception */ +#define CAL_VALUE_INT_CALENDAR_INDEX "calendar_index" /**< specific calendar id - will be remove */ +#define CAL_VALUE_DBL_LATITUDE "latitude" /**< latitude */ +#define CAL_VALUE_DBL_LONGITUDE "longitude" /**< longitude */ +#define CAL_VALUE_INT_IS_DELETED "is_deleted" /**< readonly */ +#define CAL_VALUE_TXT_TZ_NAME "tz_name" /**< tz file name */ +#define CAL_VALUE_TXT_TZ_CITY_NAME "tz_city_name" /**< tz city name */ +#define CAL_VALUE_INT_EMAIL_ID "email_id" /**< email id */ +#define CAL_VALUE_INT_AVAILABILITY "availability" +#define CAL_VALUE_GMT_CREATED_DATE_TIME "created_date_time" +#define CAL_VALUE_GMT_COMPLETED_DATE_TIME "completed_date_time" +#define CAL_VALUE_INT_PROGRESS "progress" + +/** + * @} + */ + + +/** + * @addtogroup common + * @{ + * brief + * attendee cal_value's detail field + */ +#define CAL_VALUE_LST_ATTENDEE_LIST "attendee_list" /**< attendee's detail information set */ +#define CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME "attendee_name" /**< attendee_name */ +#define CAL_VALUE_TXT_ATTENDEE_DETAIL_EMAIL "attendee_email" /**< attendee_email */ +#define CAL_VALUE_TXT_ATTENDEE_DETAIL_NUMBER "attendee_number" /**< attendee_email */ +#define CAL_VALUE_INT_ATTENDEE_DETAIL_STATUS "attendee_status" /**< #cal_event_attendee_status_type_t */ +#define CAL_VALUE_INT_ATTENDEE_DETAIL_TYPE "attendee_type" /**< #cal_event_attendee_type_t */ +#define CAL_VALUE_INT_ATTENDEE_DETAIL_CT_INDEX "attendee_ct_index" /**< contact db index for reference */ +#define CAL_VALUE_INT_ATTENDEE_ROLE "attendee_role" /**< #cal_event_attendee_role_type_t */ +#define CAL_VALUE_INT_ATTENDEE_RSVP "attendee_rsvp" +#define CAL_VALUE_TXT_ATTENDEE_GROUP "attendee_group" +#define CAL_VALUE_TXT_ATTENDEE_DELEGATOR_URI "attendee_delegator_uri" +#define CAL_VALUE_TXT_ATTENDEE_DELEGATE_URI "attendee_delegate_uri" +#define CAL_VALUE_TXT_ATTENDEE_UID "attendee_uid" + +/** + * @} + */ + +/** + * @addtogroup common + * @{ + * brief + * meeting category cal_value's detail field + */ +#define CAL_VALUE_LST_MEETING_CATEGORY "meeting_category" /**< attendee's detail information set */ +#define CAL_VALUE_INT_MEETING_CATEGORY_DETAIL_ID "event_id" /**< attendee_name */ +#define CAL_VALUE_TXT_MEETING_CATEGORY_DETAIL_NAME "category_name" /**< attendee_email */ + +/** + * @} + */ + + +/** + * @addtogroup common + * @{ + * brief + * exception event date + */ +#define CAL_VALUE_LST_EXCEPTION_DATE "exception_date" /**< exception's detail information set */ +#define CAL_VALUE_GMT_EXCEPTION_DATE_TIME "exception_date_time" /**< exception event's start date */ +#define CAL_VALUE_INT_EXCEPTION_DATE_ID "exception_event_id" /**< if occasion update case, it has valid id(not -1) */ + +/** + * @} + */ + + + +/** + * @addtogroup common + * @{ + * brief + * exception event date + */ +#define CAL_VALUE_LST_ALARM "alarm" /**< exception's detail information set */ +#define CAL_VALUE_GMT_ALARMS_TIME "alarm_time" /**< alarm time */ +#define CAL_VALUE_INT_ALARMS_TICK "remind_tick" /**< Alarms before remindTick */ +#define CAL_VALUE_INT_ALARMS_TICK_UNIT "remind_tick_unit" /**< Remind tick unit */ +#define CAL_VALUE_TXT_ALARMS_TONE "alarm_tone" /**< Alert Sound File Name */ +#define CAL_VALUE_TXT_ALARMS_DESCRIPTION "alarm_description" /**< Alert description */ +#define CAL_VALUE_INT_ALARMS_TYPE "alarm_type" /**< Alert type(see 'cal_alert_type_t') */ +#define CAL_VALUE_INT_ALARMS_ID "alarm_id" /**< Alarm id */ + +/** + * @} + */ + + + +/** + * @addtogroup common + * @{ + * brief + * delete flag in detail list + */ + +#define CAL_VALUE_INT_DETAIL_DELETE "is_deleted" /**< delete setting in detail list*/ + +/** + * @} + */ + + +/** + * @addtogroup common + * @{ + * brief + * api param + */ +#define CAL_VALUE_CUSTOM /**< custom field value(MIME Type will be Support) */ +#define CAL_VALUE_ALL_FIELD "all_field_list" /**< event's all data field return */ +#define CAL_VALUE_MAIN_FILED "main_field_list" /**< event's major data field return(summay,description,status,etc..) */ +#define CAL_VALUE_LIST_FILED "list_field_list" /**< event's sub data field for list view(summary,start/end date/all day,repeat) */ +#define CAL_VALUE_MONTH_FILED "month_field_list" /**< event's sub data field for month view check */ +/** + * @} + */ + + + +/** + * @addtogroup common + * @{ + * brief + * calendar_svc_value_xxx()'s argument for timezone + */ +/* type for timezone information save */ + +#define CAL_TZ_VALUE_INT_INDEX "index" +#define CAL_TZ_VALUE_INT_TZ_OFFSET "tz_offset_from_gmt" + +#define CAL_TZ_VALUE_TXT_STD_NAME "standard_name" +#define CAL_TZ_VALUE_INT_STD_START_MONTH "std_start_month" +#define CAL_TZ_VALUE_INT_STD_START_POSITION_OF_WEEK "std_start_position_of_week" +#define CAL_TZ_VALUE_INT_STD_START_DAY "std_start_day" +#define CAL_TZ_VALUE_INT_STD_START_HOUR "std_start_hour" +#define CAL_TZ_VALUE_INT_STD_BIAS "standard_bias" + +#define CAL_TZ_VALUE_TXT_DST_NAME "day_light_name" +#define CAL_TZ_VALUE_INT_DST_START_MONTH "day_light_start_month" +#define CAL_TZ_VALUE_INT_DST_START_POSITION_OF_WEEK "day_light_start_position_of_week" +#define CAL_TZ_VALUE_INT_DST_START_DAY "day_light_start_day" +#define CAL_TZ_VALUE_INT_DST_START_HOUR "day_light_start_hour" +#define CAL_TZ_VALUE_INT_DST_BIAS "day_light_bias" + +/** + * @} + */ + + + +/** + * @ingroup CALENDAR_SVC + * @defgroup service_management service_management + * @brief + * calendar service module management + */ + +/** + * @fn int calendar_svc_connect(void); + * This function opens database,it is must be called before other data operaion. + * + * @ingroup service_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre none + * @post calendar_svc_close() should be called when leave. + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + //..do some operation to database + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_close(). + */ +int calendar_svc_connect(void); + +/** + * @fn int calendar_svc_close(void); + * This function closes database,it is must be called when leave. + * + * @ingroup service_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre the database connected + * @post none + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + //..do some operation to database + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_connect(). + */ +int calendar_svc_close(void); + +/** + * @fn int calendar_svc_begin_trans(void); + * This function start db transaction,it is coninient for user do many operaion once. + * + * @ingroup service_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post calendar_svc_end_trans() should be called when leave + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + // begin transaction + calendar_svc_begin_trans(); + + //..do some operation to database + + // end transaction + calendar_svc_end_trans(); + + //close database + calendar_svc_close(); + + } + * @endcode + * @see calendar_svc_end_trans(). + */ +int calendar_svc_begin_trans(void); + +/** + * @fn int calendar_svc_end_trans(void); + * This function finish db transaction,it is coninient for user do many operaion once. + * + * @ingroup service_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected and calendar_svc_begin_trans() is called. + * @post none + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + // begin transaction + calendar_svc_begin_trans(); + + //..do some operation to database + + // end transaction + calendar_svc_end_trans(); + + //close database + calendar_svc_close(); + + } + * @endcode + * @see calendar_svc_begin_trans(). + */ +int calendar_svc_end_trans(void); + + +/** + * @fn int calendar_svc_subscribe_db_change (const char *data_type,void(*cb)(void *), void *user_data); + * This function registers callback function in receiver,it is convenient for user receive noti from database. + * + * @ingroup service_management + * @param[in] datatype for subscribe detail db change + * @param[in] cb Fuction pointer of calendar notification callback + * @param[in] user_data when cb function is called, user_data will be passed. + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + #include + + int received_cb (void *user_data) + { + if(NULL != user_data) + { + printf("enter received_cb:%s\n",(char*)user_data); + } + } + + void sample_code() + { + //connect database + calendar_svc_connect(); + + char* user_data = "Get a noti!\n"; + calendar_svc_subscribe_db_change (CAL_STRUCT_SCHEDULE,received_cb, user_data); + + GMainLoop* loop = g_main_loop_new(NULL,TRUE); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_unsubscribe_db_change(). + */ +int calendar_svc_subscribe_db_change (const char *data_type,void(*cb)(void *), void *user_data); + + +int calendar_svc_subscribe_change (void(*cb)(void *), void *user_data); + + +/** + * @fn int calendar_svc_unsubscribe_db_change (const char *data_type,void(*cb)(void *)); + * This function deregisters callback function in receiver,it is convenient for user unscribe some receive noti from database. + * + * @ingroup service_management + * @param[in] datatype for subscribe detail db change + * @param[in] cb Fuction pointer of calendar notification callback + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre calendar_svc_subscribe_change called + * @post none + * @code + #include + + int received_cb (void *user_data) + { + if(NULL != user_data) + { + printf("enter received_cb:%s\n",(char*)user_data); + } + } + + void sample_code() + { + //connect database + calendar_svc_connect(); + + char* user_data = "Get a noti!\n"; + calendar_svc_unsubscribe_db_change (CAL_STRUCT_SCHEDULE,received_cb, user_data); + + cal_struct * event = calendar_svc_struct_new(CAL_STRUCT_SCHEDULE); + calendar_svc_insert(event); + + GMainLoop* loop = g_main_loop_new(NULL,TRUE); + g_main_loop_run(loop); + + //... + + //close database + calendar_svc_close(); + calendar_svc_unsubscribe_db_change (CAL_STRUCT_SCHEDULE,received_cb); + } + * @endcode + * @see calendar_svc_subscribe_change(). + */ +int calendar_svc_unsubscribe_db_change (const char *data_type,void(*cb)(void *)); + + +int calendar_svc_unsubscribe_change (void(*cb)(void *)); + + + +/** + * @defgroup event_management event_management + * @ingroup CALENDAR_SVC + * @brief + * major data access api + */ + + +/** + * @fn int calendar_svc_insert(cal_struct *record); + * This function insert records to database,user can save event through calling it. + * + * @ingroup event_management + * @param[in] record calendar data for add + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks event should . + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + //create the variable + cal_struct* event = calendar_svc_struct_new("schedule"); + + //insert the event + calendar_svc_insert(event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_insert(cal_struct *record); + + + +/** + * @fn int calendar_svc_update(cal_struct *record); + * This function updates record to database,it is convenient for user to update some record. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] record calendar data for update + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + cal_struct* event = NULL; + int index = 1; + + //connect to database + calendar_svc_connect(); + + //get the record whose index is 1 + calendar_svc_get("schedule",index,NULL,&event); + + //modify the summary + calendar_svc_struct_set_str(event,"summary","weekend"); + + //update + calendar_svc_update(event); + + //free + calendar_svc_free(&evnet); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_update(cal_struct *record); + +/** + * @fn int calendar_svc_delete(const char *data_type,int index); + * This function delete records from database,it is convenient for user to delete some record. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] data_type sepecific record type + * @param[in] index event db index + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + int index = 1; + + //connect to database + calendar_svc_connect(); + + //delete the record whose index is 1 + calendar_svc_delete("schedule",index); + + //free + calendar_svc_free(&evnet); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_delete(const char *data_type,int index); + +/** + * @fn int calendar_svc_event_delete_by_period(int account_id,time_t start_time,time_t end_time); + * This function delete records from database,it is convenient for user to delete records set once. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @param[in] start_time timestamp + * @param[in] end_time timestamp + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + time_t start_time = time(NULL); + time_t end_time = start_time + 10000; + + //connect to database + calendar_svc_connect(); + + //delete the records whose lase modified time is between start_time and end_time + calendar_svc_event_delete_by_period(0,start_time,end_time); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + * @see + */ +int calendar_svc_event_delete_by_period(int account_id,time_t start_time,time_t end_time); + +/** + * @fn int calendar_svc_delete_all(int account_id,const char *data_type); + * This function delete all records from database,it is convenient for user to delete all of records. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @param[in] data_type detail data type(eg. CAL_STRUCT_CALENDAR,CAL_STRUCT_SCHEDULE, NULL), if null delete all data by account_id + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + //delete the all records of schudule_table + calendar_svc_delete_all(0,"schedule"); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ + +int calendar_svc_delete_all(int account_id,const char *data_type); + +/** + * @fn int calendar_svc_delete_account(int account_id); + * This function delete all records from database,it is convenient for user to delete all of records according to account. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + //delete the all records of schudule_table + calendar_svc_delete_account(0); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ + +int calendar_svc_delete_account(int account_id); + + +/** + * @fn int calendar_svc_clean_after_sync(int account_id); + * This function clean deleted(marked) all records from database,which is used to remove data from database after sync operation. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + //delete the all records from schudule_table + calendar_svc_clean_after_sync(0); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ + +int calendar_svc_clean_after_sync(int account_id); + +/** + * @fn int calendar_svc_get(const char *data_type,int index,const char *field_list, cal_struct **record); + * This function get records from database,user can get event from database through calling it. + * + * @ingroup event_management + * @return This function returns inserted contact id or error code on failure. + * @param[in] data_type sepecific record type + * @param[in] index db index + * @param[in] field_list specific field list(eg. "summary,description"), if NULL, all field is returned. + * @param[out] record calendar data , it should be free by calendar_svc_struct_free + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks event should . + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + int index = 1; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //get the record whose index is 1 + calendar_svc_get("schedule",index,NULL, &event); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_get(const char *data_type,int index,const char *field_list, cal_struct **record); + +/** + * @fn int calendar_svc_get_count(int account_id,int calendar_id,const char *data_type); + * This function get count of records from database,user can get the count through calling it. + * + * @ingroup event_management + * @return Integer value, or 0 if no value is obtained + * @param[in] account_id account db index + * @param[in] calendar_id calendar id(will be support phase 2) + * @param[in] data_type data_type(CAL_STRUCT_CALENDAR or CAL_STRUCT_SCHEDULE) + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks event should . + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + int count = -1; + + //connect to database + calendar_svc_connect(); + + //get the count of all + count = calendar_svc_get_count(0,0,"shchedule"); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_get_count(int account_id,int calendar_id,const char *data_type); + +/** + * @fn int calendar_svc_get_all(int account_id,int calendar_id,const char *data_type, cal_iter **iter); + * This function get all records from database,it is convenient for user to get all of the reocrds once. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @param[in] calendar_id calendar id. If account_id is set, the account_id will be ignore. + * @param[in] data_type data_type(CAL_STRUCT_CALENDAR or CAL_STRUCT_SCHEDULE) + * @param[out] iter calendar data + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks event should . + * @pre database connected + * @post call calendar_svc_iter_remove() when leave + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + + //connect to database + calendar_svc_connect(); + + //get all records + calendar_svc_get_all(0,0,"schedule", &iter); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_get_all(int account_id,int calendar_id,const char *data_type, cal_iter **iter); + + +/** + * @fn int calendar_svc_get_list(int account_id,int calendar_id,const char *data_type,const char *field_type,int offset,int count, cal_iter **iter) + * This function get all records from database,but, this api support data filter for performance. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @param[in] calendar_id calendar id(will be support phase 2) + * @param[in] data_type data_type(CAL_STRUCT_CALENDAR or CAL_STRUCT_SCHEDULE) + * @param[in] sub field type(CAL_VALUE_ALL_FIELD or CAL_VALUE_MAIN_FILED,CAL_VALUE_LIST_FILED,CAL_VALUE_MONTH_FILED) + * @param[in] offset start item list index + * @param[in] count return data count(limit count) + * @param[out] iter calendar data + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks event should . + * @pre database connected + * @post call calendar_svc_iter_remove() when leave + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + + //connect to database + calendar_svc_connect(); + + //get all records + calendar_svc_get_list(ALL_VISIBILITY_ACCOUNT,ALL_CALENDAR_ID,CAL_STRUCT_SCHEDULE,CAL_VALUE_LIST_FILED,0,10, &iter); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_get_list(int account_id,int calendar_id,const char *data_type,const char *field_type,int offset,int count, cal_iter **iter); + + +/** + * @fn int calendar_svc_get_updated_event_list(int account_id,time_t timestamp, cal_iter **iter); + * This function get update records from database by time statmp,it is convenient for user to decide which records need to sync. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @param[in] timestamp updated timestamp + * @param[out] iter interation struct for list travel + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + time timestamp = time(NULL) - 10000; + + //connect to database + calendar_svc_connect(); + + //get events updated after timestamp + calendar_svc_get_updated_event_list(0,timestamp, &iter); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_get_updated_event_list(int account_id,time_t timestamp, cal_iter **iter); + + +/** + * @fn int calendar_svc_get_event_list_by_period(int account_id,time_t start_time,time_t end_time,cal_iter **iter); + * This function get update records from database by time statmp,it is convenient for user to get records according to time. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index(0 for all event + * @param[in] start_time timestamp + * @param[in] end_time timestamp + * @param[out] iter interation struct for list travel + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + time start_time = time(NULL); + time end_time = start_time + 10000; + + //connect to database + calendar_svc_connect(); + + //get events + calendar_svc_get_event_list_by_period(0,start_time,end_time,&iter); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_get_event_list_by_period(int account_id, + time_t start_time, + time_t end_time, + cal_iter **iter); + + +int calendar_svc_get_event_list_by_tm_period (int account_id, + int calendar_id, + struct tm* startdate, + struct tm* enddate, + cal_iter **iter); + + +int calendar_svc_convert_id_to_uid(const char *data_type,int index,char **uid); + +/** + * @fn int calendar_svc_iter_get_info(cal_iter *iter, cal_struct **row_record); + * This function get cal_value by cal_iter,it is convenient for user to get event from iter. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] iter interation struct for list travel + * @param[out] row_record detail information + * @exception None. + * @remarks row_record should be free with calendar_svc_struct_free + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + cal_struct* evnet = NULL; + + //connect to database + calendar_svc_connect(); + + //get all records + calendar_svc_get_all(0,0,"schedule", &iter); + + //get events + calendar_svc_iter_get_info(iter, &event); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_iter_get_info(cal_iter *iter, cal_struct **row_record); + + +/** + * @fn int calendar_svc_iter_next(cal_iter *iter); + * This function get cal_value by cal_iter,it is convenient for user to get record one by one. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] iter interation struct for list travel + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + cal_struct* evnet = NULL; + + //connect to database + calendar_svc_connect(); + + //get all records + calendar_svc_get_all(0,0,"schedule", &iter); + + //get events + calendar_svc_iter_get_info(iter, &event); + + //get next event + calendar_svc_iter_next(iter); + calendar_svc_iter_get_info(iter, &event); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_iter_next(cal_iter *iter); + + +/** + * @fn int calendar_svc_iter_remove(cal_iter **iter); + * This function remove db iteration struct,it is convenient for user to avoid memory leak. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] iter interation struct for list travel + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + + //connect to database + calendar_svc_connect(); + + //get all records + calendar_svc_get_all(0,0,"schedule", &iter); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + */ +int calendar_svc_iter_remove(cal_iter **iter); + +/** + * @fn int calendar_svc_util_next_valid_event_tm ( cal_struct * event,struct tm* start_tm,struct tm* end_tm,struct tm* next_valid_start_tm,struct tm* next_valid_end_tm ); + * This function gets next valid event(it should be recurrence event) by period,user can get next valid event't time through calling it. + * + * @ingroup event_management + * @param[in] event point of event struct + * @param[in] start_time start point of valid time period + * @param[in] end_time end point of valid time period + * @param[out] next_valid_start_time next valid start time in period + * @param[out] next_valid_end_time next valid end time in period + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none + * @pre the event must be recurrence event + * @post none + * @code + #include + #include + void sample_code() + { + cal_struct* event = NULL; + index = 1; + time_t start_time = time(NULL); + time_t end_time = start_time + 1000000; + time_t next_valid_start_time = 0; + time_t next_valid_end_time = 0; + struct tm stm,etm; + struct tm estm,eetm; + + localtime_r(&start_time,&stm); + localtime_r(&end_time,&etm); + + //connect to database + calendar_svc_connect(); + + //get the record + calendar_svc_get("schedule",NULL,index,&event); + + //get the next valid event time + memset(&estm,0x00,sizeof(struct tm)); + memset(&eetm,0x00,sizeof(struct tm)); + while(calendar_svc_util_next_valid_event_tm(event,&stm,&etm,&estm,&eetm)==CAL_SUCCESS) + { + //using estm,eetm + } + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + + } + * @endcode + * @see none. + */ +int calendar_svc_util_next_valid_event_tm ( cal_struct * event, + struct tm* start_tm, + struct tm* end_tm, + struct tm* next_valid_start_tm, + struct tm* next_valid_end_tm ); + + +/** + * @defgroup detail_management detail_management + * @ingroup CALENDAR_SVC + * @brief + * deatil field access api + */ + + +/** + * @fn cal_struct * calendar_svc_struct_new(const char *data_type); + * This function alloc calendar struct,it is convenient for user to create an event. + * + * @ingroup detail_management + * @return This function returns allocated event struct + * @param[in] data_type (eg.CAL_EVENT_TYPE_SCHEDULE,CAL_EVENT_TYPE_CALENDAR..) + * @exception None. + * @remarks it should be free with calendar_svc_struct_free + * @pre cal_struct variable is defined. + * @post None. + * @remarks None. + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + //create variable + cal_struct * event = calendar_svc_struct_new("schedule"); + + //free the space + calendar_svc_struct_free(&event); + + //close the database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_free(). + */ +cal_struct * calendar_svc_struct_new(const char *data_type); + +/** + * @fn int calendar_svc_struct_free(cal_struct **record); + * This function is used to free space malloced to cal_struct variable,it is convenient for user to avoid memory leak when using cal_struct. + * + * @ingroup detail_management + * @param[in] record Point to alloced address + * @return This function returns CAL_SUCCESS or error code on failure. + * @pre cal_struct variable is defined. + * @post None. + * @remarks None. + * @code + #include + void sample_code() + { + //connect to database + calendar_svc_connect(); + + //create variable + cal_struct * event = calendar_svc_struct_new("schedule"); + + //free the space + calendar_svc_struct_free(&event); + + //close the database + calendar_svc_close(); + } + * @endcode + * @see common, CAL_STRUCT_TYPE , calendar_svc_struct_new. + */ +int calendar_svc_struct_free(cal_struct **record); + + +/** + * @fn int calendar_svc_struct_get_str(cal_struct* record, const char* field); + * This function gets the point of string value of the calendar service value,it is convenient for user get the value needed without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the string value in calendar service value. + * @return string value(should not be freed), or NULL if no value is obtained + * @remarks if parent cal_struct is destroyed, return string is not valid. + * @pre cal_struct varibale is defined. + * @post none + * @code + #include + void sample_code() + { + char* summary = NULL; + index = 1; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //get the record + calendar_svc_get("schedule",index,NULL,&event); + + //get the str value + summary = calendar_svc_struct_get_str(event,CAL_VALUE_TXT_SUMMARY); + + //free space + calendar_svc_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_set_str(). + */ +char *calendar_svc_struct_get_str(cal_struct* record, const char *field); + +/** + * @fn int calendar_svc_struct_get_int(cal_struct* record, const char* field); + * This function gets Integer value of the calendar service value,it is convenient for user get the value needed without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the integer value in calendar service value. + * @return Integer value, or 0 if no value is obtained + * @remarks none + * @pre cal_struct varibale is defined. + * @post none + * @code + #include + void sample_code() + { + int account_id = 0; + index = 1; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //get the record + calendar_svc_get("schedule",index,NULL,&event); + + //get the int value + account_id = calendar_svc_struct_get_int(event,CAL_VALUE_INT_ACCOUNT_ID); + + //free space + calendar_svc_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_set_int(). + */ +int calendar_svc_struct_get_int(cal_struct* record, const char *field); + + +/** + * @fn struct tm* calendar_svc_struct_get_tm(cal_struct* record, const char* field, int timezone_flag); + * This function gets time value of the calendar service value,it is convenient for user get the value needed without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the integer value in calendar service value. + * @param[in] timezone_flag #cal_timezone_flag time flag means 'time' value is local or gmt time(CAL_TZ_FLAG_GMT or CAL_TZ_FLAG_LOCAL) + * @return Integer value, or 0 if no value is obtained + * @remarks none + * @pre cal_struct varibale is defined. + * @post none + * @code + #include + #include + void sample_code() + { + time_t last_modified_time = 0; + index = 1; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //get the record + calendar_svc_get("schedule",index,NULL,&event); + + //get the time value + last_modified_time = calendar_svc_struct_get_time(event,CAL_VALUE_GMT_LAST_MODIFIED_TIME,CAL_TZ_FLAG_GMT); + + //free space + calendar_svc_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_set_time(). + */ +struct tm* calendar_svc_struct_get_tm(cal_struct* record, const char *field, int timezone_flag); + + + +/** + * @fn double calendar_svc_struct_get_double(cal_struct* record, const char* field); + * This function gets double value of the calendar service value,it is convenient for user get the value needed without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the integer value in calendar service value. + * @return double value, or 0.0 if no value is obtained + * @remarks none + * @pre cal_struct varibale is defined. + * @post none + * @code + #include + void sample_code() + { + double latitude = 0.0; + index = 1; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //get the record + calendar_svc_get("schedule",index,NULL,&event); + + //get the double value + latitude = calendar_svc_struct_get_double(event,CAL_VALUE_DBL_LATITUDE); + + //free space + calendar_svc_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_set_double(). + */ +double calendar_svc_struct_get_double(cal_struct* record, const char *field); + + +/** + * @fn int calendar_svc_struct_set_double(cal_struct* record, const char* field,double value); + * This function sets double value of the calendar service value,it is convenient for user set the value without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the integer value in calendar service value. + * @param[in] value The dobule value to be set. + * @return Integer value, or 0 if no value is obtained + * @remarks none. + * @pre cal_struct variable is defined. + * @post the corresponding value of cal_struct is set. + * @code + #include + void sample_code() + { + double latitude = 3.14; + index = 0; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create a cal_struct variable + event = calendar_svc_struct_new("schedule"); + + //set the double value + calendar_svc_set_double(event,CAL_VALUE_DBL_LATITUDE,latitude); + + //insert the record + index = calendar_svc_insert(event); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_get_double(). + */ +int calendar_svc_struct_set_double(cal_struct* record, const char *field,double value); + + +/** + * @fn int calendar_svc_struct_set_int(cal_struct* record, const char* field, int intval); + * This function sets integer value to the calendar service value,it is convenient for user set the value without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the integer value in calendar service value. + * @param[in] intval The integer value to be set. + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none. + * @pre cal_struct variable is defined. + * @post the corresponding value of cal_struct is set. + * @code + #include + void sample_code() + { + int account_id = 1; + index = 0; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create a cal_struct variable + event = calendar_svc_struct_new("schedule"); + + //set the int value + calendar_svc_set_int(event,CAL_VALUE_INT_ACCOUNT_ID,account_id); + + //insert the record + index = calendar_svc_insert(event); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_get_int(). + */ +int calendar_svc_struct_set_int(cal_struct* record, const char *field, int intval); + +/** + * @fn int calendar_svc_struct_set_str(cal_struct* record, const char* field, const char *strval); + * This function sets string value to the calendar service value,it is convenient for user set the value without knowing the detail of the struct. + * If it is in struct, free old string and copy strval to struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the string value in calendar service value. + * @param[in] strval The string value to be set. + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none. + * @pre cal_struct variable is defined. + * @post the corresponding value of cal_struct is set. + * @code + #include + void sample_code() + { + char* summary = "party"; + index = 0; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create a cal_struct variable + event = calendar_svc_struct_new("schedule"); + + //set the string value + calendar_svc_set_str(event,CAL_VALUE_TXT_SUMMARY,summary); + + //insert the record + index = calendar_svc_insert(event); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_get_str(). + */ +int calendar_svc_struct_set_str(cal_struct* record, const char *field, const char *strval); + + +/** + * @fn int calendar_svc_struct_set_tm(cal_struct* record, const char* field,int timezone_flag, struct tm* time); + * This function sets time value of the calendar service value,it is convenient for user set the value without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the integer value in calendar service value. + * @param[in] timezone_flag #cal_timezone_flag time flag means 'time' value is local or gmt time(CAL_TZ_FLAG_GMT or CAL_TZ_FLAG_LOCAL) + * @param[in] time time value in calendar service value. + * @return Integer value, or 0 if no value is obtained + * @remarks none. + * @pre cal_struct variable is defined. + * @post the corresponding value of cal_struct is set. + * @code + #include + #include + void sample_code() + { + time_t last_modified_time = time(NULL); + index = 0; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create a cal_struct variable + event = calendar_svc_struct_new("schedule"); + + //set the time value + calendar_svc_set_time(event,CAL_VALUE_GMT_LAST_MODIFIED_TIME,CAL_TZ_FLAG_GMT,last_modified_time); + + //insert the record + index = calendar_svc_insert(event); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_get_time(). + */ +int calendar_svc_struct_set_tm(cal_struct* record, const char *field, int timezone_flag,struct tm* time); + +/** + * @fn int calendar_svc_struct_get_list(cal_struct* record, const char* field, GList** retlist); + * This function gets the point of glib double-linked list in the calendar service struct,it is convenient for user get the value without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record structure A calendar service struct + * @param[in] field The index of the glib singly-linked list in calendar service struct. + * @param[out] retlist the glib singly-linked list requested with field(should not be freed or removed) + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks if parent cal_struct is destroyed, retlist is not valid. + * @pre cal_struct variable is defined. + * @post none. + * @code + #include + void sample_code() + { + GList* list = NULL; + index = 1; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //get the record + calendar_svc_get("schedule",index,NULL,&event); + + //get the list + calendar_svc_struct_get_list(event,"attendee_list",&list); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_store_list(). + */ +int calendar_svc_struct_get_list(cal_struct* record,const char *field, GList** retlist); + +/** + * @fn int calendar_svc_struct_store_list(cal_struct* record, const char* field, GList* list) + * This function sets the glib double-linked list to the calendar service struct,it is convenient for user set the value. + * \n Values(cal_value) of the list are moved to the calendar service struct. But the list is copied. + * + * @ingroup detail_management + * @param[in] record structure A calendar service struct + * @param[in] field The index of the glib singly-linked list in calendar service struct. + * @param[in] list the glib singly-linked list to be set + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks if parent cal_struct is destroyed, GSList is not valid. + * @pre cal_struct variable is defined. + * @post none. + * @code + #include + void sample_code() + { + GList* list = NULL; + index = 1; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_struct_new("schedule"); + + //set the list + calendar_svc_struct_store_list(event,"attendee_list",list); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_get_list(). + */ +int calendar_svc_struct_store_list(cal_struct* record,const char *field, GList* list); + +/** + * @fn int calendar_svc_value_new(const char* val_type); + * Allocate, initialize and return a new calendar service value,it is convenient for user to create a calendar service value. + * + * @ingroup detail_management + * @param[in] val_type The type of calendar service value + * @return The pointer of New calendar service value, NULL on error + * @remarks none. + * @pre none. + * @post none. + * @code + #include + void sample_code() + { + GList* list = NULL; + index = 1; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new("attendee_list"); + + //set the list + list = g_list_append(list,event); + calendar_svc_struct_store_list(event,"attendee_list",list); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_free(). + */ +cal_value* calendar_svc_value_new(const char *val_type); + +/** + * @fn int calendar_svc_value_free(cal_value** value); + * A destructor for calendar service value,,it is convenient for user to free the space allocated. + * If it is in struct, return CAL_ERR_ARG_INVALID. + * + * @ingroup detail_management + * @param[in] value A calendar service value + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none. + * @pre cal_value variable is defined. + * @post none. + * @code + #include + void sample_code() + { + GList* list = NULL; + index = 1; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new("attendee_list"); + + //set the list + list = g_list_append(list,event); + calendar_svc_struct_store_list(event,"attendee_list",list); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_new(). + */ +int calendar_svc_value_free(cal_value** value); + +/** + * @fn int calendar_svc_value_set_int(cal_value* value, const char* field, int intval); + * This function sets integer value to the calendar service value,it is convenient for user set value of cal_value varible. + * + * @ingroup detail_management + * @param[in] value The calendar service value + * @param[in] field The index of the integer value in calendar service value. + * @param[in] intval The integer value to be set. + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none. + * @pre cal_value variable is defined. + * @post none. + * @code + #include + void sample_code() + { + GList* list = NULL; + index = 1; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new("attendee_list"); + calendar_svc_value_set_int(event,"attendee_status",1); + + //set the list + list = g_list_append(list,event); + calendar_svc_struct_store_list(event,"attendee_list",list); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_get_int(). + */ +int calendar_svc_value_set_int(cal_value* value, const char *field, int intval); + +/** + * @fn int calendar_svc_value_set_str(cal_value* value, const char* field, const char *strval); + * This function sets string value to the calendar service value,it is convenient for user set value of cal_value varible. + * If it is in struct, free old string and copy strval to struct. + * + * @ingroup detail_management + * @param[in] value The calendar service value + * @param[in] field The index of the string value in calendar service value. + * @param[in] strval The string value to be set. + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none. + * @pre cal_value variable is defined. + * @post none. + * @code + #include + void sample_code() + { + GList* list = NULL; + index = 1; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new("attendee_list"); + calendar_svc_value_set_str(event,"attendee_name","Max"); + + //set the list + list = g_list_append(list,event); + calendar_svc_struct_store_list(event,"attendee_list",list); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_get_str(). + */ +int calendar_svc_value_set_str(cal_value* value, const char *field, const char *strval); + + + +/** + * @fn int calendar_svc_value_set_time(cal_value* value, const char* field,int timezone_flag, time_t time); + * This function sets time value of the calendar service value,it is convenient for user set value of cal_value varible. + * + * @ingroup detail_management + * @param[in] value The calendar service value + * @param[in] field The index of the integer value in calendar service value. + * @param[in] timezone_flag #cal_timezone_flag time flag means 'time' value is local or gmt time(CAL_TZ_FLAG_GMT or CAL_TZ_FLAG_LOCAL) + * @param[in] time timestamp value in calendar service value. + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none. + * @pre cal_value variable is defined. + * @post none. + * @code + #include + void sample_code() + { + GList* list = NULL; + index = 1; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new(CAL_VALUE_LST_EXCEPTION_DATE); + calendar_svc_value_set_time(event,CAL_VALUE_GMT_EXCEPTION_DATE_TIME,CAL_TZ_FLAG_GMT,time(NULL)); + + //set the list + list = g_list_append(list,event); + calendar_svc_struct_store_list(event,CAL_VALUE_LST_EXCEPTION_DATE,list); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_get_time(). + */ +int calendar_svc_value_set_tm (cal_value *value, const char *field,int timezone_flag, struct tm* time); + +/** + * @fn int calendar_svc_value_get_int(cal_value* value, const char* field); + * This function gets Integer value of the calendar service value,it is convenient for user get value of cal_value varible. + * + * @ingroup detail_management + * @param[in] value The calendar service value + * @param[in] field The index of the integer value in calendar service value. + * @return Integer value, or 0 if no value is obtained + * @remarks none. + * @pre cal_value variable is defined. + * @post none. + * @code + #include + void sample_code() + { + int event_id = 0; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new("meeting_category"); + + //get the event_id value + event_id = calendar_svc_value_get_int(event,"event_id"); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_set_int(). + */ +int calendar_svc_value_get_int(cal_value* value, const char *field); + +/** + * @fn char* calendar_svc_value_get_str(cal_value* value, const char* field); + * This function gets the point of string value of the calendar service value,it is convenient for user get value of cal_value varible. + * + * @ingroup detail_management + * @param[in] value The calendar service value + * @param[in] field The index of the string value in calendar service value. + * @return string value(should not be freed), or NULL if no value is obtained + * @remarks none. + * @pre cal_value variable is defined. + * @post none. + * @code + #include + void sample_code() + { + char* category_name = "money"; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new("meeting_category"); + + //get the event_id value + category_name = calendar_svc_value_get_str(event,"category_name"); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_set_str(). + */ +char *calendar_svc_value_get_str(cal_value* value, const char *field); + + + +/** + * @fn time_t calendar_svc_value_get_time(cal_value* value, const char* field,int timezone_flag); + * This function gets time value of the calendar service value,it is convenient for user get value of cal_value varible. + * + * @ingroup detail_management + * @param[in] value The calendar service value + * @param[in] field The index of the integer value in calendar service value. + * @param[in] timezone_flag #cal_timezone_flag time flag means 'time' value is local or gmt time(CAL_TZ_FLAG_GMT or CAL_TZ_FLAG_LOCAL) + * @return time time value in calendar service value. + * @remarks none. + * @pre cal_value variable is defined. + * @post none. + * @code + #include + #include + void sample_code() + { + time_t exception_time = 0; + index = 1; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new(CAL_VALUE_LST_EXCEPTION_DATE); + exception_time = calendar_svc_value_get_time(event,CAL_VALUE_GMT_EXCEPTION_DATE_TIME,CAL_TZ_FLAG_GMT); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_set_time(). + */ +struct tm* calendar_svc_value_get_tm (cal_value *value, const char *field,int timezone_flag); + + + +/** + * @defgroup utilities utilities + * @ingroup CALENDAR_SVC + * @brief + * date/time, timzone utilities + */ + +/** + * @fn int calendar_svc_util_convert_db_time (struct tm* fromTime,char* fromTz, struct tm *toTime, char *toTz); + * This function gets local time by gmt0 time,it is convenient for user to convert time. + */ +int calendar_svc_util_convert_db_time (struct tm* fromTime,char *fromTz, struct tm *toTime, char *toTz); + + +/** + * @fn int calendar_svc_util_gmt_to_local(time_t fromTime,time_t *toTime); + * This function gets local time by gmt0 time,it is convenient for user to convert time. + * + * @ingroup utilities + * @param[in] fromTime gmt0 time + * @param[out] toTime local time + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none + * @pre none + * @post none + * @code + #include + #include + void sample_code() + { + time_t fromTime = time(NULL); + time_t toTime = 0; + + //connect to database + calendar_svc_connect(); + + //convert + calendar_svc_util_gmt_to_local(fromTime,&toTime); + + //close to database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_util_local_to_gmt(). + */ +int calendar_svc_util_gmt_to_local(time_t fromTime,time_t *toTime); + +/** + * @fn int calendar_svc_util_local_to_gmt(time_t fromTime,time_t *toTime); + * This function gets gmt0 time by local time,it is convenient for user to convert time. + * + * @ingroup utilities + * @param[in] fromTime local time + * @param[out] toTime gmt0 time + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none + * @pre none + * @post none + * @code + #include + #include + void sample_code() + { + time_t fromTime = time(NULL); + time_t toTime = 0; + + //connect to database + calendar_svc_connect(); + + //convert + calendar_svc_util_local_to_gmt(fromTime,&toTime); + + //close to database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_util_gmt_to_local(). + */ +int calendar_svc_util_local_to_gmt(time_t fromTime,time_t *toTime); + + +/** + * @fn int calendar_svc_util_save_vcs_by_index(const int index,char* full_file_path); + * This function makes vcal file by record index,it is convenient for user to get vcal from the calendar record. + * + * @ingroup utilities + * @param[in] index event's index for vcal converting + * @param[out] full_file_path Points the file path. + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none + * @pre none + * @post none + * @code + #include + #include + void sample_code() + { + char* full_file_path = "/opt/dbspace"; + int index = 1; + + //connect to database + calendar_svc_connect(); + + //convert + calendar_svc_util_save_vcs_by_index(index,full_file_path); + + //close to database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_util_register_vcs_file(),calendar_svc_util_convert_vcs_to_event(). + */ +int calendar_svc_util_save_vcs_by_index(const int index,char *full_file_path); + +/** + * @fn int calendar_svc_util_register_vcs_file(const char * file_name); + * This function registers vcal to calendar db,user can save vcal to database through calling it. + * + * @ingroup utilities + * @param[in] file_name vcalendar's file name + * @return This function returns cid or error code on failure. + * @remarks none + * @pre the vcalendar exists + * @post none + * @code + #include + void sample_code() + { + char* full_name = "/opt/dbspace/vcalendar_test.vcs"; + int cal_id = 0; + + //connect to database + calendar_svc_connect(); + + //convert + cal_id = calendar_svc_util_register_vcs_file(full_name); + + //close to database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_util_save_vcs_by_index(),calendar_svc_util_convert_vcs_to_event(). + */ +int calendar_svc_util_register_vcs_file(const char * file_name); + +/** + * @fn int calendar_svc_util_convert_vcs_to_event (const char *raw_data,int data_size,cal_struct **record); + * This function converts data (raw_data(vcal format) to cal_struct(event)),it is convenient for user to convert. + * + * @ingroup utilities + * @param[in] raw_data vcalendar event raw data + * @param[in] data_size raw_data buf size + * @param[out] record assigned record + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none + * @pre the vcalendar data is valid. + * @post none + * @code + #include + void sample_code() + { + char raw_data[] = "";//raw data + + //connect to database + calendar_svc_connect(); + + cal_struct* event = NULL; + + //convert + calendar_svc_util_convert_vcs_to_event (raw_data,strlen(raw_data),&event); + + calendar_svc_struct_free(&event); + + //close to database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_util_convert_event_to_vcs(). + */ +int calendar_svc_util_convert_vcs_to_event (const char *raw_data,int data_size,cal_struct **record); + +/** + * @fn int calendar_svc_util_convert_event_to_vcs (cal_struct *record,char **raw_data,int *data_size); + * This function converts data (cal_struct(event) to raw_data(vcal format)),it is convenient for user to convert. + * + * @ingroup utilities + * @param[in] record original record type + * @param[out] raw_data vcalendar event raw data + * @param[out] data_size raw_data buf size + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none + * @pre none. + * @post none + * @code + #include + void sample_code() + { + char raw_data = NULL; + int data_size = 0; + + //connect to database + calendar_svc_connect(); + + cal_struct* event = NULL; + + //get the record + calendar_svc_get("schedule",1,NULL,&event); + + //convert + calendar_svc_util_convert_event_to_vcs (event,&raw_data,&data_size); + + calendar_svc_struct_free(&event); + + //close to database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_util_convert_vcs_to_event(). + */ +int calendar_svc_util_convert_event_to_vcs (cal_struct *record,char **raw_data,int *data_size); + + +/** + * @fn int calendar_svc_util_next_valid_event(cal_struct* event,time_t start_time,time_t end_time,time_t *next_valid_start_time,time_t *next_valid_end_time); + * This function gets next valid event(it should be recurrence event) by period,user can get next valid event't time through calling it. + * + * @ingroup utilities + * @param[in] event point of event struct + * @param[in] start_time start point of valid time period + * @param[in] end_time end point of valid time period + * @param[out] next_valid_start_time next valid start time in period + * @param[out] next_valid_end_time next valid end time in period + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none + * @pre the event must be recurrence event + * @deprecated this api will be deprecated. + * @post none + * @code + #include + #include + void sample_code() + { + cal_struct* event = NULL; + index = 1; + time_t start_time = time(NULL); + time_t end_time = start_time + 1000000; + time_t next_valid_start_time = 0; + time_t next_valid_end_time = 0; + + //connect to database + calendar_svc_connect(); + + //get the record + calendar_svc_get("schedule",NULL,index,&event); + + //get the next valid event time + calendar_svc_util_next_valid_event(event,start_time,end_time,&next_valid_start_time,&next_valid_end_time); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + + } + * @endcode + * @see none. + */ +int calendar_svc_util_next_valid_event(cal_struct* event,time_t start_time,time_t end_time, + time_t *next_valid_start_time,time_t *next_valid_end_time); + +/** + * @fn time_t calendar_svc_value_get_time(cal_value* value, const char* field,int timezone_flag); + * This function gets time value of the calendar service value,it is convenient for user get value of cal_value varible. + * + * @ingroup detail_management + * @param[in] value The calendar service value + * @param[in] field The index of the integer value in calendar service value. + * @param[in] timezone_flag #cal_timezone_flag time flag means 'time' value is local or gmt time(CAL_TZ_FLAG_GMT or CAL_TZ_FLAG_LOCAL) + * @return time time value in calendar service value. + * @remarks none. + * @pre cal_value variable is defined. + * @deprecated this api will be deprecated. + * @post none. + * @code + #include + #include + void sample_code() + { + time_t exception_time = 0; + index = 1; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new(CAL_VALUE_LST_EXCEPTION_DATE); + exception_time = calendar_svc_value_get_time(event,CAL_VALUE_GMT_EXCEPTION_DATE_TIME,CAL_TZ_FLAG_GMT); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_set_time(). + */ +time_t calendar_svc_value_get_time(cal_value* value, const char *field,int timezone_flag); + +/** + * @fn int calendar_svc_value_set_time(cal_value* value, const char* field,int timezone_flag, time_t time); + * This function sets time value of the calendar service value,it is convenient for user set value of cal_value varible. + * + * @ingroup detail_management + * @param[in] value The calendar service value + * @param[in] field The index of the integer value in calendar service value. + * @param[in] timezone_flag #cal_timezone_flag time flag means 'time' value is local or gmt time(CAL_TZ_FLAG_GMT or CAL_TZ_FLAG_LOCAL) + * @param[in] time timestamp value in calendar service value. + * @return This function returns CAL_SUCCESS or error code on failure. + * @remarks none. + * @pre cal_value variable is defined. + * @post none. + * @deprecated this api will be deprecated. + * @code + #include + void sample_code() + { + GList* list = NULL; + index = 1; + cal_value* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create the event + event = calendar_svc_value_new(CAL_VALUE_LST_EXCEPTION_DATE); + calendar_svc_value_set_time(event,CAL_VALUE_GMT_EXCEPTION_DATE_TIME,CAL_TZ_FLAG_GMT,time(NULL)); + + //set the list + list = g_list_append(list,event); + calendar_svc_struct_store_list(event,CAL_VALUE_LST_EXCEPTION_DATE,list); + + //free the space + calendar_svc_value_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_value_get_time(). + */ +int calendar_svc_value_set_time(cal_value* value, const char *field,int timezone_flag, time_t time); + +/** + * @fn int calendar_svc_struct_set_time(cal_struct* record, const char* field,int timezone_flag, time_t time); + * This function sets time value of the calendar service value,it is convenient for user set the value without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the integer value in calendar service value. + * @param[in] timezone_flag #cal_timezone_flag time flag means 'time' value is local or gmt time(CAL_TZ_FLAG_GMT or CAL_TZ_FLAG_LOCAL) + * @param[in] time time value in calendar service value. + * @return Integer value, or 0 if no value is obtained + * @remarks none. + * @pre cal_struct variable is defined. + * @post the corresponding value of cal_struct is set. + * @deprecated this api will be deprecated. + * @code + #include + #include + void sample_code() + { + time_t last_modified_time = time(NULL); + index = 0; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //create a cal_struct variable + event = calendar_svc_struct_new("schedule"); + + //set the time value + calendar_svc_set_time(event,CAL_VALUE_GMT_LAST_MODIFIED_TIME, CAL_TZ_FLAG_GMT, last_modified_time); + + //insert the record + index = calendar_svc_insert(event); + + //free the space + calendar_svc_struct_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_set_tm(). + */ +int calendar_svc_struct_set_time(cal_struct* record, const char *field,int timezone_flag, time_t time); + +/** + * @fn time_t calendar_svc_struct_get_time(cal_struct* record, const char* field, int timezone_flag); + * This function gets time value of the calendar service value,it is convenient for user get the value needed without knowing the detail of the struct. + * + * @ingroup detail_management + * @param[in] record Point to The calendar struct + * @param[in] field The index of the integer value in calendar service value. + * @param[in] timezone_flag #cal_timezone_flag time flag means 'time' value is local or gmt time(CAL_TZ_FLAG_GMT or CAL_TZ_FLAG_LOCAL) + * @return Integer value, or 0 if no value is obtained + * @remarks none + * @pre cal_struct varibale is defined. + * @post none + * @deprecated this api will be deprecated. + * @code + #include + #include + void sample_code() + { + time_t last_modified_time = 0; + index = 1; + cal_struct* event = NULL; + + //connect to database + calendar_svc_connect(); + + //get the record + calendar_svc_get("schedule",index,NULL,&event); + + //get the time value + last_modified_time = calendar_svc_struct_get_time(event,CAL_VALUE_GMT_LAST_MODIFIED_TIME); + + //free space + calendar_svc_free(&event); + + //close database + calendar_svc_close(); + } + * @endcode + * @see calendar_svc_struct_get_tm(). + */ +time_t calendar_svc_struct_get_time(cal_struct* record, const char *field, int timezone_flag); + +/** + * @fn void calendar_svc_util_get_local_tz_info(char **lock_city_name,char **lock_tz_path,char** lock_tz_offset,char **local_city_name,char **local_tz_path,char **local_tz_offset); + get timezone information by setting value + * @deprecated it will be deprecated. + */ +void calendar_svc_util_get_local_tz_info(char **lock_city_name,char **lock_tz_path,char** lock_tz_offset, + char **local_city_name,char **local_tz_path,char **local_tz_offset); + +/** + * @fn int calendar_svc_find_event_list(int account_id,const char* search_type,const void* search_value, cal_iter **iter); + * This function get records from database by search param,it is convenient for user to get records according to some condition. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @param[in] search_type event search type(eg. CAL_VALUE_SUMMARY or CAL_VALUE_DESCRIPTION,..) + * @param[in] search_value event search value(eg. "weekly report", etc.. ), it can be integer value(eg. 1 or 2.. etc) + * @param[out] iter interation struct for list travel + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + + //connect to database + calendar_svc_connect(); + + //find event whose summary including string like "party" + calendar_svc_find_event_list(0,"summary","party", &iter); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + * @deprecated it will replacement calendar_svc_find_list + */ +int calendar_svc_find_event_list(int account_id,const char *search_type,const void* search_value, cal_iter **iter); + +int calendar_svc_find_recurring_event_list (int account_id, cal_iter **iter); + +int calendar_svc_find_event_list_by_filter(int account_id, int filter_count, const char *search_type[], const void *search_value[], cal_iter **iter); + +/** + * @fn int calendar_svc_find(int account_id,int calendar_id,const char *data_type,const char *search_type,const void *search_value, cal_iter **iter); + * This function get records from database by search param,it is convenient for user to get records according to some condition. + * + * @ingroup event_management + * @return This function returns CAL_SUCCESS or error code on failure. + * @param[in] account_id account db index + * @param[in] calendar_id calendar db index + * @param[in] data_type struct type(CAL_STRUCT_SCHEDULE,CAL_STRUCT_CALENDAR,CAL_STRUCT_TIMEZONE,..) + * @param[in] search_type event search type(eg. CAL_VALUE_SUMMARY or CAL_VALUE_DESCRIPTION,..) + * @param[in] search_value event search value(eg. "weekly report", etc.. ), it can be integer value(eg. 1 or 2.. etc) + * @param[out] iter interation struct for list travel + * @return This function returns CAL_SUCCESS or error code on failure. + * @exception None. + * @remarks None. + * @pre database connected + * @post none + * @code + #include + void sample_code() + { + cal_iter *iter = NULL; + + //connect to database + calendar_svc_connect(); + + //find event whose summary including string like "party" + calendar_svc_find(LOCAL_ACCOUNT_ID,DEFAULT_CALENDAR_ID,CAL_STRUCT_SCHEDULE,"summary","party", &iter); + + //free + calendar_svc_iter_remove(&iter); + + //close database + calendar_svc_close(); + } + * @endcode + * @see detail_management module + * @deprecated it will replacement calendar_svc_find_list + */ +int calendar_svc_find(int account_id,int calendar_id,const char *data_type,const char *search_type,const void *search_value, cal_iter **iter); + + +/** + * @fn int calendar_svc_search_list(int account_id,int calendar_id,const char *data_type,const char *search_type,const void *search_value,int offset,int count, cal_iter **iter); + * This function get records from database by search param,it is convenient for user to get records according to some condition. + + * @deprecated it will replacement calendar_svc_find_list + **/ +int calendar_svc_search_list(int account_id,int calendar_id,const char *data_type,const char *search_type,const void *search_value, + int offset,int count, cal_iter **iter); + + +#ifdef __cplusplus +} +#endif + +typedef enum +{ + CAL_STATUS_FREE = 0, /**< deprecated */ + CAL_STATUS_TENTATIVE, /**< deprecated */ + CAL_STATUS_BUSY, /**< deprecated */ + CAL_STATUS_OUROFOFFICE, /**< deprecated */ + CAL_STATUS_CONFIRM, /**< deprecated */ + CAL_STATUS_DENIED, /**< deprecated */ +} cal_status_type_t; + +#endif /* __CALENDAR_SVC_H__ */ + diff --git a/include/calendar-svc-struct.h b/include/calendar-svc-struct.h new file mode 100755 index 0000000..1857301 --- /dev/null +++ b/include/calendar-svc-struct.h @@ -0,0 +1,259 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_STRUCT_H__ +#define __CALENDAR_SVC_STRUCT_H__ + + +/** + * @defgroup CALENDAR_SVC Calendar Service + * @section intro 2.0 calendar engine + * - this document maded for calendar service + * - this document contain api signature & usage + * + * @section CREATEINFO author infomation + * - author : heungjae jeong(hj98.jeong@samsung.com) + * - date : 2010/09/06 + * + * @section DEPENDENCY DEPENDENCY + * - GLIB + * + * @section MODIFYINFO Revision history + * - maximus/2010-09-06 : make api signature + * - maximus/2010-09-16 : add calendar type & exception date, change api name(remove _event) + * - maximus/2010-09-16 : add utility function(for vcalendar) + * + * + */ + + +/** + *cal_struct is an opaque type, it must be used via accessor functions. + *@ingroup common + *@see also: + * calendar_svc_struct_new(), calendar_svc_struct_free() + * calendar_svc_struct_get_value(), calendar_svc_struct_get_list(), + * calendar_svc_struct_store_value(), calendar_svc_struct_store_list() + */ +typedef struct _cal_struct cal_struct; + + +/** + * cal_value is an opaque type, it must be + * used via accessor functions. + * @ingroup common + * @see calendar_svc_struct_new(), calendar_svc_struct_free() + */ +typedef struct _cal_value cal_value; + + + +/** + * cal_struct is an opaque type, it must be used via accessor functions. + * @ingroup common + * @see calendar_svc_find_event_list(), calendar_svc_get_updated_event_list() + * calendar_svc_get_event_by_period(), calendar_svc_iter_get_info(), + * calendar_svc_iter_next(), calendar_svc_iter_remove() + */ +typedef struct _cal_iter cal_iter; + + + +/** + * @defgroup example example + * @ingroup CALENDAR_SVC + * @li + * insert example + * @code + void insert_test(void) + { + cal_struct *event=NULL; + cal_value *attendee1=NULL,*attendee2=NULL; + GList *attendee_list=NULL; + + calendar_svc_connect(); + event = calendar_svc_struct_new(CAL_STRUCT_SCHEDULE); + + calendar_svc_struct_set_str(event, CAL_VALUE_TXT_SUMMARY, "weekly meeting"); + calendar_svc_struct_set_str(event, CAL_VALUE_TXT_DESCRIPTION, "review : project status"); + calendar_svc_struct_set_str(event, CAL_VALUE_TXT_LOCATION, "meeting room #1"); + + attendee1 = calendar_svc_value_new(CAL_VALUE_LST_ATTENDEE_LIST); + if(attendee1) { + calendar_svc_value_set_str(attendee1, CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME, "heungjae jeong"); + calendar_svc_value_set_str(attendee1, CAL_VALUE_TXT_ATTENDEE_DETAIL_EMAIL, "id@domain.com"); + calendar_svc_value_set_int(attendee1, CAL_VALUE_INT_ATTENDEE_DETAIL_STATUS, 1); + } + attendee_list = g_list_append(attendee_list, attendee1); + + attendee2 = calendar_svc_value_new(CAL_VALUE_LST_ATTENDEE_LIST); + if(attendee2) { + calendar_svc_value_set_str(attendee2, CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME, "boncheol gu"); + calendar_svc_value_set_str(attendee2, CAL_VALUE_TXT_ATTENDEE_DETAIL_EMAIL, "id@domain.com"); + calendar_svc_value_set_str(attendee2, CAL_VALUE_INT_ATTENDEE_DETAIL_STATUS, 0); + } + attendee_list = g_list_append(attendee_list, attendee2); + + calendar_svc_struct_store_list(event, CAL_VALUE_LST_ATTENDEE_LIST, attendee_list); + + calendar_svc_insert(event); + calendar_svc_struct_free(&event); + + calendar_svc_close(); + } + * @endcode + */ + +/** + * @addtogroup example + * @li + * update example + * @code + void update_test(void) + { + cal_struct *event=NULL; + cal_value *attendee1,*attendee2; + GList *attendee_list=NULL; + char * attendee_name = NULL; + + calendar_svc_connect(); + + calendar_svc_get(CAL_STRUCT_SCHEDULE,1,&event) + + calendar_svc_struct_set_str(event, CAL_VALUE_TXT_SUMMARY, "weekly meeting2"); + + attendee_list = calendar_svc_struct_get_list(event,CAL_VALUE_LST_ATTENDEE_LIST); + + while(attendee_list) + { + + attendee1 = attendee_list->data; + + attendee_name = calendar_svc_value_get_str(attendee2, CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME); + + if(strcmp(attendee_name,"boncheol gu")==0) + { + calendar_svc_value_set_str(attendee1, CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME,"boncheol gu2"); + } + else if(strcmp(attendee_name,"heungjae jeong")==0) + { + calendar_svc_value_set_int(attendee1, CAL_VALUE_INT_DETAIL_DELETE,true); // set delete flag + } + } + + attendee2 = calendar_svc_value_new(CAL_VALUE_LST_ATTENDEE_LIST); + if(attendee2) { + calendar_svc_value_set_str(attendee2, CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME, "jihwa park"); + calendar_svc_value_set_str(attendee2, CAL_VALUE_TXT_ATTENDEE_DETAIL_EMAIL, "id@domain.com"); + } + attendee_list = g_list_append(attendee_list, attendee2); + + calendar_svc_struct_store_list(event, CAL_VALUE_LST_ATTENDEE_LIST, attendee_list); + + calendar_svc_update(event); + calendar_svc_struct_free(&event); + + calendar_svc_close(); + } + * @endcode + */ + + +/** + * @addtogroup example + * @li + * get list/delete example + * @code + void delete_test(void) + { + cal_struct *event=NULL; + cal_value *attendee1=NULL,*attendee2=NULL; + GList *attendee_list=NULL; + time_t cur_time = 0; + cal_iter *iter=NULL; + int ret = 0; + int index = 0; + + cur_time = time(NULL); + calendar_svc_connect(); + + calendar_svc_get_updated_event_list(0, cur_time,&iter); + ret = calendar_svc_iter_next(iter); + while(CAL_SUCCESS == ret) + { + calendar_svc_iter_get_info(iter, &event); + index = calendar_svc_struct_get_int(event,CAL_VALUE_INT_INDEX); + + calendar_svc_delete(CAL_STRUCT_SCHEDULE,index); + + calendar_svc_struct_free(&event); + ret = calendar_svc_iter_next(iter); + } + + calendar_svc_iter_remove(&iter); + calendar_svc_close(); + } + * @endcode + */ + + + +/** + * @addtogroup example + * @li + * get event example + * @code + + void get_test(void) + { + int index, ret=-1; + cal_struct *event = NULL; + cal_value *name; + GList *get_list, *cursor; + index = 1; + char *summary; + ui_event_t appEvent={0,}; + + ret = calendar_svc_get(CAL_STRUCT_SCHEDULE,index,CAL_VALUE_MAIN_FILED, &event); + + summary = calendar_svc_struct_get_str(event, CAL_VALUE_TXT_SUMMARY); + strncpy(appEvent.summay,summary,sizeof(appEvent.summay)-1); + + + get_list = NULL; + calendar_svc_struct_get_list(event, CAL_VALUE_LST_ATTENDEE_LIST, &get_list); + + cursor = get_list; + for(;cursor;cursor=g_slist_next(cursor)) + { + DBG("number Type = %d", + calendar_svc_value_get_int((cal_value*)cursor->data, CAL_VALUE_INT_ATTENDEE_DETAIL_STATUS)); + + DBG("Number = %s\n", + calendar_svc_value_get_str((cal_value*)cursor->data, CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME)); + } + + calendar_svc_struct_free(&event); + + } +* @endcode +*/ + + +#endif /* __CALENDAR_SVC_STRUCT_H__ */ + diff --git a/include/cals-db-info.h b/include/cals-db-info.h new file mode 100755 index 0000000..8b36c45 --- /dev/null +++ b/include/cals-db-info.h @@ -0,0 +1,39 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_DB_INFO_H__ +#define __CALENDAR_SVC_DB_INFO_H__ + +#define CALS_DB_PATH "/opt/dbspace/.calendar-svc.db" +#define CALS_DB_JOURNAL_PATH "/opt/dbspace/.calendar-svc.db-journal" + +// For Security +#define CALS_SECURITY_FILE_GROUP 6003 +#define CALS_SECURITY_DEFAULT_PERMISSION 0660 +#define CALS_SECURITY_DIR_DEFAULT_PERMISSION 0770 + +#define CALS_TABLE_SCHEDULE "schedule_table" +#define CALS_TABLE_ALARM "cal_alarm_table" +#define CALS_TABLE_CALENDAR "calendar_table" +#define CALS_TABLE_RECURRENCY_LOG "recurrency_log_table" +#define CALS_TABLE_PARTICIPANT "cal_participant_table" +#define CALS_TABLE_MEETING_CATEGORY "cal_meeting_category_table" +#define CALS_TABLE_TIMEZONE "timezone_table" + +#endif /* __CALENDAR_SVC_DB_INFO_H__ */ + diff --git a/include/cals-internal.h b/include/cals-internal.h new file mode 100755 index 0000000..7513d2f --- /dev/null +++ b/include/cals-internal.h @@ -0,0 +1,117 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_INTERNAL_H__ +#define __CALENDAR_SVC_INTERNAL_H__ + +#include +#include +#include + +#define EVENT_UPDATE "calendar_event_update" +#define CALENDARBOOK_UPDATE "calendar_book_update" +#define TASK_UPDATE "task_update" + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#define SAFE_STRDUP(src) (src)?strdup((char *)src):NULL + +#define CALS_DEBUGGING + +#define LOG_TAG "CALENDAR_SVC" +#include +#define DLOG(prio, fmt, arg...) \ + do { SLOG(prio, LOG_TAG, fmt, ##arg); } while(0); +#define INFO(fmt, arg...) SLOGI(fmt, ##arg) +#define ERR(fmt, arg...) SLOGE("%s:%d " fmt, __FUNCTION__, __LINE__, ##arg) +#define DBG(fmt, arg...) SLOGD("%s:" fmt, __FUNCTION__, ##arg) + +//#define CALS_DEBUGGING +#ifdef CALS_DEBUGGING +#define CALS_FN_CALL DBG(">>>>>>>>%s called", __FUNCTION__) +#define CALS_FN_END DBG("<<<<<<<<%s ended", __FUNCTION__) +#define CALS_DBG(fmt, arg...) DBG("%d " fmt, __LINE__, ##arg) +#else /* CALS_DEBUGGING */ +#define CALS_FN_CALL +#define CALS_FN_END +#define CALS_DBG(fmt, arg...) +#endif /* CALS_DEBUGGING */ + + +#define TMDUMP(_X_)\ +{\ + ERR("tm(%d/%d/%d %d:%d)",(_X_).tm_year+1900,(_X_).tm_mon+1,(_X_).tm_mday,(_X_).tm_hour,(_X_).tm_min);\ +} + +#define warn_if(expr, fmt, arg...) do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + } \ +} while (0) +#define ret_if(expr) do { \ + if (expr) { \ + ERR("(%s)", #expr); \ + return; \ + } \ +} while (0) +#define retv_if(expr, val) do { \ + if (expr) { \ + ERR("(%s)", #expr); \ + return (val); \ + } \ +} while (0) +#define retm_if(expr, fmt, arg...) do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + return; \ + } \ +} while (0) +#define retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + ERR(fmt, ##arg); \ + return (val); \ + } \ +} while (0) + +#define retex_if(expr, val, fmt, arg...) do { \ + if(expr) { \ + ERR(fmt, ##arg); \ + val; \ + goto CATCH; \ + } \ + } while (0); + +#define CAL_PROFILE +#ifdef CAL_PROFILE +#define CAL_PROFILE_GET_TIME() (clock() / (CLOCKS_PER_SEC / 1000)); +#define CAL_PROFILE_PRINT(starttime,endtime) ERR("%ld ~ %ld : %ld(%d sec) msec",starttime,endtime,endtime-starttime,(endtime-starttime)/1000); +#else +#define CAL_PROFILE_GET_TIME(input_time) 0 +#define CAL_PROFILE_PRINT(starttime,endtime) +#endif + +#define CAL_FREE(ptr) \ + do { \ + free(ptr); \ + ptr = NULL; \ + }while(0); + +#endif /* __CALENDAR_SVC_INTERNAL_H__ */ + diff --git a/packaging/libslp-calendar.spec b/packaging/libslp-calendar.spec new file mode 100644 index 0000000..e65a9e2 --- /dev/null +++ b/packaging/libslp-calendar.spec @@ -0,0 +1,82 @@ +Name: libslp-calendar +Summary: DB library for calendar +Version: 0.1.10 +Release: 12 +Group: System/Libraries +License: Apache 2.0 +Source0: %{name}-%{version}.tar.gz +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +BuildRequires: cmake +BuildRequires: pkgconfig(db-util) +BuildRequires: pkgconfig(gmodule-2.0) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(alarm-service) +Requires(post): /usr/bin/sqlite3 + +%description +DB library for calendar + +%package devel +Summary: DB library for calendar +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +DB library for calendar (developement files) + +%prep +%setup -q + + +%build +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} + + +make %{?jobs:-j%jobs} + +%install +%make_install + + +%post +/sbin/ldconfig +mkdir -p /opt/dbspace +if [ -f /opt/dbspace/.calendar-svc.db ] +then + echo "calendar.db exist" +else + calendar-svc-initdb +fi + +#chown :5000 /opt/dbspace +chown :6003 /opt/dbspace/.calendar-svc.db +chown :6003 /opt/dbspace/.calendar-svc.db-journal +chown :6003 /opt/data/calendar-svc/.CALENDAR_SVC_* + +# Change file permissions +#chmod 644 /usr/lib/libcalendar-service.so +#chmod 775 /opt/dbspace +chmod 660 /opt/dbspace/.calendar-svc.db +chmod 660 /opt/dbspace/.calendar-svc.db-journal +chmod 660 /opt/data/calendar-svc/.CALENDAR_SVC_* + +%postun -p /sbin/ldconfig + + +%files +%defattr(-,root,root,-) +%attr(0660,root,db_calendar)/opt/data/calendar-svc/.CALENDAR_SVC_* +/usr/lib/libcalendar-service.so.0* +/usr/lib/libcalendar-service.so.0.1.12 + + +%files devel +%defattr(-,root,root,-) +/usr/lib/pkgconfig/calendar-service.pc +/usr/include/calendar/calendar-svc-errors.h +/usr/include/calendar/calendar-svc-provider.h +/usr/include/calendar/calendar-svc-struct.h +/usr/lib/libcalendar-service.so diff --git a/schema/CMakeLists.txt b/schema/CMakeLists.txt new file mode 100755 index 0000000..96aff0f --- /dev/null +++ b/schema/CMakeLists.txt @@ -0,0 +1,24 @@ +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src) +LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) + +SET(TARGET calendar-svc-initdb) + +EXECUTE_PROCESS(COMMAND ./generator.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +FILE(GLOB SRCS *.c) + +pkg_check_modules(initdb_pkgs REQUIRED db-util dlog) + +UNSET(EXTRA_CFLAGS) +FOREACH(flag ${initdb_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_EXECUTABLE(${TARGET} ${SRCS}) +SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS}) +TARGET_LINK_LIBRARIES(${TARGET} ${initdb_pkgs_LDFLAGS}) + +INSTALL(TARGETS ${TARGET} DESTINATION bin) diff --git a/schema/generator.sh b/schema/generator.sh new file mode 100755 index 0000000..123460b --- /dev/null +++ b/schema/generator.sh @@ -0,0 +1,29 @@ +# +# Calendar Service +# +# Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#!/bin/sh + +echo "###### API Generator #####" + +cd header-gen +make + +# Schema +./schema-header-gen ../schema.sql > ../schema.h + +make clean diff --git a/schema/header-gen/Makefile b/schema/header-gen/Makefile new file mode 100755 index 0000000..70b2727 --- /dev/null +++ b/schema/header-gen/Makefile @@ -0,0 +1,22 @@ +CC = gcc + +REQUIRED_PKG = +CFLAGS = -g -Wall #-fprofile-arcs -ftest-coverage +LDFLAGS = +ifdef REQUIRED_PKG + CFLAGS += `pkg-config --cflags $(REQUIRED_PKG)` + LDFLAGS += `pkg-config --libs $(REQUIRED_PKG)` +endif + +SRCS = $(wildcard *.c) +OBJECTS = $(SRCS:.c=.o) +TARGETS = $(OBJECTS:.o=) + +all: $(TARGETS) + +% : %.o + $(CC) $(LDFLAGS) -o $@ $< + +clean: + rm -rf $(OBJECTS) $(TARGETS) + diff --git a/schema/header-gen/schema-header-gen.c b/schema/header-gen/schema-header-gen.c new file mode 100755 index 0000000..6836a30 --- /dev/null +++ b/schema/header-gen/schema-header-gen.c @@ -0,0 +1,59 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include + +int main(int argc, char **argv) +{ + FILE *fp; + int c; + + fp = fopen(argv[1], "r"); + if (fp == NULL) + exit(EXIT_FAILURE); + + printf("static const char *schema_query = \"\\\n"); + + do{ + c = fgetc(fp); + switch (c) + { + case '\n': + printf("\\\n"); + break; + case '-': + if ('-' == (c = fgetc(fp))) { + while ('\n' != c && EOF != c) + c = fgetc(fp); + printf("\\\n"); + } + else printf("-%c",c); + break; + case EOF: + break; + default: + printf("%c",c); + break; + } + }while(EOF != c); + printf("\";\n"); + + exit(EXIT_SUCCESS); +} + diff --git a/schema/initdb.c b/schema/initdb.c new file mode 100755 index 0000000..0767003 --- /dev/null +++ b/schema/initdb.c @@ -0,0 +1,87 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include + +#include "schema.h" +#include "cals-db-info.h" +#include "cals-internal.h" +#include "calendar-svc-errors.h" + + +static inline int remake_db_file() +{ + int ret, fd; + char *errmsg; + sqlite3 *db; + + ret = db_util_open(CALS_DB_PATH, &db, 0); + retvm_if(SQLITE_OK != ret, CAL_ERR_DB_NOT_OPENED, "db_util_open() Failed(%d)", ret); + + ret = sqlite3_exec(db, schema_query, NULL, 0, &errmsg); + if (SQLITE_OK != ret) { + ERR("remake calendar DB file is Failed : %s", errmsg); + sqlite3_free(errmsg); + } + + db_util_close(db); + + fd = open(CALS_DB_PATH, O_CREAT | O_RDWR, 0660); + retvm_if(-1 == fd, CAL_ERR_FAIL, "open Failed"); + + fchown(fd, getuid(), CALS_SECURITY_FILE_GROUP); + fchmod(fd, CALS_SECURITY_DEFAULT_PERMISSION); + close(fd); + + fd = open(CALS_DB_JOURNAL_PATH, O_CREAT | O_RDWR, 0660); + retvm_if(-1 == fd, CAL_ERR_FAIL, "open Failed"); + + fchown(fd, getuid(), CALS_SECURITY_FILE_GROUP); + fchmod(fd, CALS_SECURITY_DEFAULT_PERMISSION); + close(fd); + + return CAL_SUCCESS; +} + +static inline int check_db_file(void) +{ + int fd = open(CALS_DB_PATH, O_RDONLY); + retvm_if(-1 == fd, -1, + "DB file(%s) is not exist", CALS_DB_PATH); + + close(fd); + return CAL_SUCCESS; +} + +static inline int check_schema(void) +{ + if (check_db_file()) + remake_db_file(); + + return CAL_SUCCESS; +} + +int main(int argc, char **argv) +{ + return check_schema(); +} diff --git a/schema/schema.sql b/schema/schema.sql new file mode 100755 index 0000000..c8b4960 --- /dev/null +++ b/schema/schema.sql @@ -0,0 +1,189 @@ +-- +-- Calendar Service +-- +-- Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +CREATE TABLE schedule_table +( +id INTEGER PRIMARY KEY AUTOINCREMENT, +account_id INTEGER, +type INTEGER, +category INTEGER, +summary TEXT, +description TEXT, +location TEXT, +all_day_event INTEGER, +start_date_time INTEGER, +end_date_time INTEGER, +repeat_item INTEGER, +repeat_interval INTEGER, +repeat_occurrences INTEGER, +repeat_end_date INTEGER, +sun_moon INTEGER, +week_start INTEGER, +week_flag TEXT, +day_date INTEGER, +last_modified_time INTEGER, +missed INTEGER, +task_status INTEGER, +priority INTEGER, +timezone INTEGER, +file_id INTEGER, +contact_id INTEGER, +busy_status INTEGER, +sensitivity INTEGER, +uid TEXT, +calendar_type INTEGER, +organizer_name TEXT, +organizer_email TEXT, +meeting_status INTEGER, +gcal_id TEXT, +deleted INTEGER, +updated TEXT, +location_type INTEGER, +location_summary TEXT, +etag TEXT, +calendar_id INTEGER, +sync_status INTEGER, +edit_uri TEXT, +gevent_id TEXT, +dst INTEGER, +original_event_id INTEGER, +latitude DOUBLE, +longitude DOUBLE, +is_deleted INTEGER, +tz_name TEXT, +tz_city_name TEXT, +email_id INTEGER, +availability INTEGER, +created_date_time INTEGER, +completed_date_time INTEGER, +progress INTEGER +); +CREATE INDEX sch_idx1 ON schedule_table(type, category); +CREATE TRIGGER trg_sch_del AFTER DELETE ON schedule_table + BEGIN + DELETE FROM cal_alarm_table WHERE event_id = old.id; + END; + +CREATE TABLE cal_participant_table +( +event_id INTEGER, +attendee_name TEXT, +attendee_email TEXT, +attendee_number TEXT, +attendee_status INTEGER, +attendee_type INTEGER, +attendee_ct_index INTEGER, +attendee_role INTEGER, +attendee_rsvp INTEGER, +attendee_group TEXT, +attendee_delegator_uri TEXT, +attendee_delegate_uri TEXT, +attendee_uid TEXT +); + +CREATE TABLE cal_meeting_category_table +( +event_id INTEGER, +category_name TEXT +); + +CREATE TABLE recurrency_log_table +( +uid TEXT, +start_date_time INTEGER, +end_date_time INTEGER, +event_id INTEGER, +exception_event_id INTEGER, +updated INTEGER +); + +CREATE TABLE calendar_table +( +calendar_id TEXT, +uid TEXT, +link TEXT, +updated INTEGER, +name TEXT, +description TEXT, +author TEXT, +color TEXT, +hidden INTEGER, +selected INTEGER, +location TEXT, +locale INTEGER, +country INTEGER, +time_zone INTEGER, +timezone_label TEXT, +display_all_timezones INTEGER, +date_field_order INTEGER, +format_24hour_time INTEGER, +week_start INTEGER, +default_cal_mode INTEGER, +custom_cal_mode INTEGER, +user_location TEXT, +weather TEXT, +show_declined_events INTEGER, +hide_invitations INTEGER, +alternate_calendar INTEGER, +visibility INTEGER, +projection INTEGER, +sequence INTEGER, +suppress_reply_notifications INTEGER, +sync_event INTEGER, +times_cleaned INTEGER, +guests_can_modify INTEGER, +guests_can_invite_others INTEGER, +guests_can_see_guests INTEGER, +access_level INTEGER, +sync_status INTEGER, +is_deleted INTEGER, +account_id INTEGER, +sensitivity INTEGER, +store_type INTEGER +); + +CREATE TABLE timezone_table +( +tz_offset_from_gmt INTEGER, +standard_name TEXT, +std_start_month INTEGER, +std_start_position_of_week INTEGER, +std_start_day INTEGER, +std_start_hour INTEGER, +standard_bias INTEGER, +day_light_name TEXT, +day_light_start_month INTEGER, +day_light_start_position_of_week INTEGER, +day_light_start_day INTEGER, +day_light_start_hour INTEGER, +day_light_bias INTEGER +); + +CREATE TABLE cal_alarm_table +( +event_id INTEGER, +alarm_time INTEGER, +remind_tick INTEGER, +remind_tick_unit INTEGER, +alarm_tone TEXT, +alarm_description TEXT, +alarm_type INTEGER, +alarm_id INTEGER +); + +INSERT INTO calendar_table VALUES(0,0,0,0,'default calendar',0,0,'76.198.86.255',0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,-1,0,3); diff --git a/src/cals-alarm.c b/src/cals-alarm.c new file mode 100755 index 0000000..6f5486c --- /dev/null +++ b/src/cals-alarm.c @@ -0,0 +1,335 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include + +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-db-info.h" +#include "cals-sqlite.h" +#include "cals-tz-utils.h" +#include "cals-utils.h" +#include "cals-alarm.h" + +#define PKG_CALENDAR_APP "org.tizen.calendar" + +int cals_alarm_remove(int type, int related_id) +{ + int ret; + sqlite3_stmt *stmt = NULL; + char query[CALS_SQL_MAX_LEN] = {0}; + + switch (type) { + case CALS_ALARM_REMOVE_BY_EVENT_ID: + sprintf(query, "SELECT alarm_id FROM %s " + "WHERE event_id = %d AND alarm_id <> 0", CALS_TABLE_ALARM, related_id); + break; + case CALS_ALARM_REMOVE_BY_CALENDAR_ID: + sprintf(query, "SELECT alarm_id FROM %s A, %s B ON A.id = B.event_id " + "WHERE A.calendar_id = %d AND B.alarm_id <> 0", + CALS_TABLE_SCHEDULE, CALS_TABLE_ALARM, related_id); + break; + case CALS_ALARM_REMOVE_BY_ACC_ID: + sprintf(query, "SELECT alarm_id FROM %s A, %s B ON A.id = B.event_id " + "WHERE A.account_id = %d AND B.alarm_id <> 0", + CALS_TABLE_SCHEDULE, CALS_TABLE_ALARM, related_id); + break; + case CALS_ALARM_REMOVE_ALL: + sprintf(query, "SELECT alarm_id FROM %s WHERE alarm_id <> 0", CALS_TABLE_ALARM); + break; + } + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + ret = cals_stmt_step(stmt); + if (ret < CAL_SUCCESS) { + sqlite3_finalize(stmt); + ERR("sqlite3_step() Failed(%d)", ret); + return CAL_ERR_DB_FAILED; + } + + while (CAL_TRUE == ret) { + alarmmgr_remove_alarm(sqlite3_column_int(stmt,0)); + ret = cals_stmt_step(stmt); + } + sqlite3_finalize(stmt); + + // TODO: If calendar service use delete_table not delete_flag, below procedure can handle by trigger. + switch (type) { + case CALS_ALARM_REMOVE_BY_EVENT_ID: + sprintf(query, "DELETE FROM %s WHERE event_id = %d", CALS_TABLE_ALARM, related_id); + break; + case CALS_ALARM_REMOVE_BY_CALENDAR_ID: + sprintf(query, "DELETE FROM %s " + "WHERE event_id IN (SELECT id FROM %s WHERE calendar_id = %d)", + CALS_TABLE_ALARM, CALS_TABLE_SCHEDULE, related_id); + break; + case CALS_ALARM_REMOVE_BY_ACC_ID: + sprintf(query, "DELETE FROM %s " + "WHERE event_id IN (SELECT id FROM %s WHERE account_id = %d)", + CALS_TABLE_ALARM, CALS_TABLE_SCHEDULE, related_id); + break; + case CALS_ALARM_REMOVE_ALL: + sprintf(query, "DELETE FROM %s", CALS_TABLE_ALARM); + break; + } + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("sqlite3_step(%s) Failed(%d)", query, ret); + return CAL_ERR_DB_FAILED; + } + sqlite3_finalize(stmt); + + return CAL_SUCCESS; +} + +static inline int _cals_alarm_add(const int event_id, cal_alarm_info_t *alarm_info) +{ + int rc = -1; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + time_t conv_alarm_time; + + conv_alarm_time = cals_mktime(&alarm_info->alarm_time); + + sprintf(sql_value, "INSERT INTO %s(event_id,alarm_time,remind_tick,remind_tick_unit,alarm_tone,alarm_description,alarm_type,alarm_id) " + "VALUES(%d,%ld,%d,%d,?,?,%d,%d)", CALS_TABLE_ALARM, + event_id, + conv_alarm_time, + alarm_info->remind_tick, + alarm_info->remind_tick_unit, + alarm_info->alarm_type, + alarm_info->alarm_id); + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + if (alarm_info->alarm_tone) + cals_stmt_bind_text(stmt, 0, alarm_info->alarm_tone); + + if (alarm_info->alarm_description) + cals_stmt_bind_text(stmt, 1, alarm_info->alarm_description); + + rc = cals_stmt_step(stmt); + if (CAL_SUCCESS != rc) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", rc); + return rc; + } + + sqlite3_finalize(stmt); + + return CAL_SUCCESS; +} + +int cals_alarm_add(int event_id, cal_alarm_info_t *alarm_info, struct tm *start_date_time) +{ + CALS_FN_CALL; + int ret = 0; + alarm_id_t alarm_id; + alarm_date_t alarm_date = {0}; + alarm_entry_t *aet = NULL; + struct tm time; + time_t base_tt, alarm_tt; + + if(alarm_info->remind_tick_unit == CAL_SCH_TIME_UNIT_OFF) + return CAL_INVALID_INDEX; + + //update the alarm time + aet = alarmmgr_create_alarm(); + retvm_if(NULL == aet, CAL_ERR_ALARMMGR_FAILED, "alarmmgr_create_alarm() Failed"); + + //calculate time + if(alarm_info->remind_tick_unit == CAL_SCH_TIME_UNIT_SPECIFIC) { + base_tt = cals_mktime(&alarm_info->alarm_time); + } else { + int sec = 0; + + switch (alarm_info->remind_tick_unit) { + case CAL_SCH_TIME_UNIT_MIN: + sec = 60; + break; + case CAL_SCH_TIME_UNIT_HOUR: + sec = 3600; + break; + case CAL_SCH_TIME_UNIT_DAY: + sec = ONE_DAY_SECONDS; + break; + case CAL_SCH_TIME_UNIT_WEEK: + sec = ONE_WEEK_SECONDS; + break; + case CAL_SCH_TIME_UNIT_MONTH: + sec = ONE_MONTH_SECONDS; + break; + case CAL_SCH_TIME_UNIT_OFF: + default: + alarmmgr_free_alarm(aet); + return CAL_INVALID_INDEX; + } + + sec = sec * alarm_info->remind_tick; + + base_tt = cals_mktime(start_date_time) - sec; + } + + calendar_svc_util_gmt_to_local(base_tt,&alarm_tt); + cals_tmtime_r(&alarm_tt,&time); + TMDUMP(time); + + alarm_date.year = time.tm_year + 1900; + alarm_date.month = time.tm_mon + 1; + alarm_date.day = time.tm_mday; + alarm_date.hour = time.tm_hour; + alarm_date.min = time.tm_min; + alarm_date.sec = time.tm_sec; + + ret = alarmmgr_set_time(aet, alarm_date); + if (ret < 0) { + alarmmgr_free_alarm(aet); + ERR("alarmmgr_set_time() Failed(%d)", ret); + return CAL_ERR_ALARMMGR_FAILED; + } + + ret = alarmmgr_set_repeat_mode(aet, 0, 0); + if (ret < 0) { + alarmmgr_free_alarm(aet); + ERR("alarmmgr_set_repeat_mode() Failed(%d)", ret); + return CAL_ERR_ALARMMGR_FAILED; + } + + ret = alarmmgr_set_type(aet, ALARM_TYPE_DEFAULT); + if (ret < 0) { + alarmmgr_free_alarm(aet); + ERR("alarmmgr_set_type() Failed(%d)", ret); + return CAL_ERR_ALARMMGR_FAILED; + } + + ret = alarmmgr_add_alarm_with_localtime(aet, PKG_CALENDAR_APP, &alarm_id); + if (ret < 0) { + alarmmgr_free_alarm(aet); + ERR("alarmmgr_add_alarm_with_localtime() Failed(%d)", ret); + return CAL_ERR_ALARMMGR_FAILED; + } + + alarmmgr_free_alarm(aet); + alarm_info->alarm_id = alarm_id; + + _cals_alarm_add(event_id, alarm_info); + + return CAL_SUCCESS; +} + + +int cals_alarm_get_event_id(int alarm_id) +{ + char query[CALS_SQL_MIN_LEN]; + + sprintf(query, "SELECT event_id FROM cal_alarm_table WHERE alarm_id=%d", alarm_id); + + return cals_query_get_first_int_result(query); +} + + +static void _cals_alarm_value_free(gpointer data, gpointer user_data) +{ + if (NULL == data) + return; + + free(((cal_alarm_info_t*)((cal_value*)data)->user_data)->alarm_tone); + free(((cal_alarm_info_t*)((cal_value*)data)->user_data)->alarm_description); + free(data); +} + + +int cals_get_alarm_info(const int event_id, GList **alarm_list) +{ + int ret = -1; + GList *result = NULL; + sqlite3_stmt *stmt = NULL; + cal_value * cvalue = NULL; + char query[CALS_SQL_MAX_LEN] = {0}; + cal_alarm_info_t* alarm_info = NULL; + + retv_if(NULL == alarm_list, CAL_ERR_ARG_NULL); + + sprintf(query, "SELECT * FROM %s WHERE event_id=%d", CALS_TABLE_ALARM, event_id); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + ret = cals_stmt_step(stmt); + if (ret < CAL_SUCCESS) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", ret); + return ret; + } + + while (CAL_TRUE == ret) + { + cvalue = calloc(1, sizeof(cal_value)); + if (NULL == cvalue) { + sqlite3_finalize(stmt); + g_list_foreach(result, _cals_alarm_value_free, NULL); + g_list_free(result); + ERR("calloc() Failed(%d)", errno); + return CAL_ERR_OUT_OF_MEMORY; + } + + cvalue->v_type = CAL_EVENT_ALARM; + cvalue->user_data = alarm_info = calloc(1, sizeof(cal_alarm_info_t)); + if (NULL == alarm_info) { + sqlite3_finalize(stmt); + g_list_foreach(result, _cals_alarm_value_free, NULL); + g_list_free(result); + free(cvalue); + ERR("calloc() Failed(%d)", errno); + return CAL_ERR_OUT_OF_MEMORY; + } + + alarm_info->event_id = sqlite3_column_int(stmt, 0); + + long int temp = 0; + temp = sqlite3_column_int(stmt, 1); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&temp),&(alarm_info->alarm_time)); + alarm_info->remind_tick = sqlite3_column_int(stmt,2); + alarm_info->remind_tick_unit = sqlite3_column_int(stmt, 3); + alarm_info->alarm_tone = SAFE_STRDUP(sqlite3_column_text(stmt, 4)); + alarm_info->alarm_description = SAFE_STRDUP(sqlite3_column_text(stmt, 5)); + alarm_info->alarm_type = sqlite3_column_int(stmt, 6); + alarm_info->alarm_id = sqlite3_column_int(stmt, 7); + + result = g_list_append(result, cvalue); + + ret = cals_stmt_step(stmt); + } + sqlite3_finalize(stmt); + + *alarm_list = result; + + return CAL_SUCCESS; +} + + diff --git a/src/cals-alarm.h b/src/cals-alarm.h new file mode 100755 index 0000000..a383468 --- /dev/null +++ b/src/cals-alarm.h @@ -0,0 +1,35 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_ALARM_H__ +#define __CALENDAR_SVC_ALARM_H__ + + +enum { + CALS_ALARM_REMOVE_BY_EVENT_ID, + CALS_ALARM_REMOVE_BY_CALENDAR_ID, + CALS_ALARM_REMOVE_BY_ACC_ID, + CALS_ALARM_REMOVE_ALL, +}; +int cals_alarm_remove(int type, int related_id); +int cals_alarm_add(int event_id, cal_alarm_info_t *alarm_info, struct tm *start_date_time); +int cals_alarm_get_event_id(int alarm_id); +int cals_get_alarm_info(const int event_id, GList **alarm_list); + + +#endif /* __CALENDAR_SVC_ALARM_H__ */ diff --git a/src/cals-calendar.c b/src/cals-calendar.c new file mode 100755 index 0000000..2aa4376 --- /dev/null +++ b/src/cals-calendar.c @@ -0,0 +1,720 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-sqlite.h" +#include "cals-db-info.h" +#include "cals-utils.h" +#include "cals-alarm.h" +#include "cals-calendar.h" + + +int cals_insert_calendar(const calendar_t *calendar) +{ + int ret; + sqlite3_stmt *stmt; + char query[CALS_SQL_MAX_LEN]; + + retv_if(NULL == calendar, CAL_ERR_ARG_NULL); + + sprintf(query,"INSERT INTO %s(calendar_id,uid,link,updated,name,description,author," + "color,hidden,selected,location,locale,country,time_zone,timezone_label,display_all_timezones," + "date_field_order,format_24hour_time,week_start,default_cal_mode,custom_cal_mode,user_location," + "weather,show_declined_events,hide_invitations,alternate_calendar,visibility,projection," + "sequence,suppress_reply_notifications,sync_event,times_cleaned,guests_can_modify," + "guests_can_invite_others,guests_can_see_guests,access_level,sync_status,account_id,sensitivity,store_type) " + "VALUES( ?, ?, ?, %ld, ?, ?, ?, ?, %d, %d, ?, %d, %d, %ld, ?, %d, %d, %d, " + "%d, %d, %d, ?, ?, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", + CALS_TABLE_CALENDAR, + //calendar->calendar_id, + //calendar->uid, + //calendar->link, + calendar->updated, + //calendar->name, + //calendar->description, + //calendar->author, + //calendar->color, + calendar->hidden, + calendar->selected, + //calendar->location, + calendar->locale, + calendar->country, + calendar->time_zone, + //calendar->timezone_label, + calendar->display_all_timezones, + calendar->date_field_order, + calendar->format_24hour_time, + calendar->week_start, + calendar->default_cal_mode, + calendar->custom_cal_mode, + //calendar->user_location, + //calendar->weather, + calendar->show_declined_events, + calendar->hide_invitations, + calendar->alternate_calendar, + calendar->visibility, + calendar->projection, + calendar->sequence, + calendar->suppress_reply_notifications, + calendar->sync_event, + calendar->times_cleaned, + calendar->guests_can_modify, + calendar->guests_can_invite_others, + calendar->guests_can_see_guests, + calendar->access_level, + calendar->sync_status, + calendar->account_id, + calendar->sensitivity, + calendar->store_type); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + if (calendar->calendar_id) + cals_stmt_bind_text(stmt, 1, calendar->calendar_id); + + if (calendar->uid) + cals_stmt_bind_text(stmt, 2, calendar->uid); + + if (calendar->link) + cals_stmt_bind_text(stmt, 3, calendar->link); + + if (calendar->name) + cals_stmt_bind_text(stmt, 4, calendar->name); + + if (calendar->description) + cals_stmt_bind_text(stmt, 5, calendar->description); + + if (calendar->author) + cals_stmt_bind_text(stmt, 6, calendar->author); + + if (calendar->color) + cals_stmt_bind_text(stmt, 7, calendar->color); + + if (calendar->location) + cals_stmt_bind_text(stmt, 8, calendar->location); + + if (calendar->timezone_label) + cals_stmt_bind_text(stmt, 9, calendar->timezone_label); + + if (calendar->user_location) + cals_stmt_bind_text(stmt, 10, calendar->user_location); + + if (calendar->weather) + cals_stmt_bind_text(stmt, 11, calendar->weather); + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", ret); + return ret; + } + + ret = cals_last_insert_id(); + sqlite3_finalize(stmt); + + cals_notify(CALS_NOTI_TYPE_CALENDAR); + + return ret; +} + +int cals_update_calendar(const calendar_t *calendar) +{ + int rc = -1; + char query[CALS_SQL_MAX_LEN] = {0}; + sqlite3_stmt *stmt = NULL; + + retv_if(NULL == calendar, CAL_ERR_ARG_NULL); + + snprintf(query, sizeof(query), "UPDATE %s SET " + "calendar_id = ?," + "link = ?," + "updated = %ld," + "name = ?," + "description = ?," + "author = ?," + "color = ?," + "hidden= %d," + "selected = %d," + "location = ?," + "locale = %d," + "country = %d," + "time_zone = %ld," + "timezone_label = ?," + "display_all_timezones = %d," + "date_field_order = %d," + "format_24hour_time = %d," + "week_start = %d," + "default_cal_mode = %d," + "custom_cal_mode = %d," + "user_location = ?," + "weather = ?," + "show_declined_events = %d," + "hide_invitations = %d," + "alternate_calendar = %d," + "visibility = %d," + "projection = %d," + "sequence = %d," + "suppress_reply_notifications = %d," + "sync_event = %d," + "times_cleaned = %d," + "guests_can_modify = %d," + "guests_can_invite_others = %d," + "guests_can_see_guests = %d," + "access_level = %d," + "sync_status = %d," + "account_id = %d," + "sensitivity = %d, " + "store_type = %d " + "WHERE rowid = %d", + CALS_TABLE_CALENDAR, + calendar->updated, + calendar->hidden, + calendar->selected, + calendar->locale, + calendar->country, + calendar->time_zone, + calendar->display_all_timezones, + calendar->date_field_order, + calendar->format_24hour_time, + calendar->week_start, + calendar->default_cal_mode, + calendar->custom_cal_mode, + calendar->show_declined_events, + calendar->hide_invitations, + calendar->alternate_calendar, + calendar->visibility, + calendar->projection, + calendar->sequence, + calendar->suppress_reply_notifications, + calendar->sync_event, + calendar->times_cleaned, + calendar->guests_can_modify, + calendar->guests_can_invite_others, + calendar->guests_can_see_guests, + calendar->access_level, + calendar->sync_status, + calendar->account_id, + calendar->sensitivity, + calendar->store_type, + calendar->index); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + if (calendar->calendar_id) + cals_stmt_bind_text(stmt, 1, calendar->calendar_id); + + if (calendar->link) + cals_stmt_bind_text(stmt, 2, calendar->link); + + if (calendar->name) + cals_stmt_bind_text(stmt, 3, calendar->name); + + if (calendar->description) + cals_stmt_bind_text(stmt, 4, calendar->description); + + if (calendar->author) + cals_stmt_bind_text(stmt, 5, calendar->author); + + if (calendar->color) + cals_stmt_bind_text(stmt, 6, calendar->color); + + if (calendar->location) + cals_stmt_bind_text(stmt, 7, calendar->location); + + if (calendar->timezone_label) + cals_stmt_bind_text(stmt, 8, calendar->timezone_label); + + if (calendar->user_location) + cals_stmt_bind_text(stmt, 9, calendar->user_location); + + if (calendar->weather) + cals_stmt_bind_text(stmt, 10, calendar->weather); + + rc = cals_stmt_step(stmt); + if (CAL_SUCCESS != rc) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", rc); + return rc; + } + + sqlite3_finalize(stmt); + + cals_notify(CALS_NOTI_TYPE_CALENDAR); + + return CAL_SUCCESS; +} + +int cals_delete_calendar(int index) +{ + int ret = 0; + char query[CALS_SQL_MAX_LEN] = {0}; + + ret = cals_begin_trans(); + retvm_if(CAL_SUCCESS != ret, ret, "cals_begin_trans() Failed(%d)", ret); + + sprintf(query,"DELETE FROM %s WHERE rowid = %d", CALS_TABLE_CALENDAR, index); + ret = cals_query_exec(query); + if(CAL_SUCCESS != ret) { + ERR("cals_query_exec() Failed(%d)", ret); + cals_end_trans(false); + return ret; + } + + time_t current_time = time(NULL); + + sprintf(query,"UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld WHERE calendar_id = %d", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time, index); + + ret = cals_query_exec(query); + if (CAL_SUCCESS != ret) { + ERR("cals_query_exec() Failed(%d)", ret); + cals_end_trans(false); + return ret; + } + ret = cals_alarm_remove(CALS_ALARM_REMOVE_BY_CALENDAR_ID, index); + if (CAL_SUCCESS != ret) { + ERR("cals_alarm_remove() Failed(%d)", ret); + cals_end_trans(false); + return ret; + } + + cals_end_trans(true); + + cals_notify(CALS_NOTI_TYPE_CALENDAR); + return CAL_SUCCESS; +} + + +int cals_delete_calendars(int account_id) +{ + int ret = 0; + char query[CALS_SQL_MIN_LEN] = {0}; + + if (account_id) + sprintf(query,"DELETE FROM calendar_table WHERE account_id = %d", account_id); + else + sprintf(query,"DELETE FROM calendar_table"); + + ret = cals_query_exec(query); + retvm_if(CAL_SUCCESS != ret, ret, "cals_query_exec() Failed(%d)", ret); + + cals_notify(CALS_NOTI_TYPE_CALENDAR); + return CAL_SUCCESS; +} + + +void cals_stmt_get_calendar(sqlite3_stmt *stmt,calendar_t *record) +{ + int count = 0; + const unsigned char *temp; + + record->index = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + record->calendar_id = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + record->uid = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + record->link = SAFE_STRDUP(temp); + + record->updated = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + record->name = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + record->description = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + record->author = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + record->color = SAFE_STRDUP(temp); + + record->hidden = sqlite3_column_int(stmt, count++); + record->selected = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + record->location = SAFE_STRDUP(temp); + + record->locale = sqlite3_column_int(stmt, count++); + record->country = sqlite3_column_int(stmt, count++); + record->time_zone = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + record->timezone_label = SAFE_STRDUP(temp); + + record->display_all_timezones = sqlite3_column_int(stmt, count++); + record->date_field_order = sqlite3_column_int(stmt, count++); + record->format_24hour_time = sqlite3_column_int(stmt, count++); + record->week_start = sqlite3_column_int(stmt, count++); + record->default_cal_mode = sqlite3_column_int(stmt, count++); + record->custom_cal_mode = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + record->user_location = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + record->weather = SAFE_STRDUP(temp); + + record->show_declined_events = sqlite3_column_int(stmt, count++); + record->hide_invitations = sqlite3_column_int(stmt, count++); + record->alternate_calendar = sqlite3_column_int(stmt, count++); + record->visibility = sqlite3_column_int(stmt, count++); + record->projection = sqlite3_column_int(stmt, count++); + record->sequence = sqlite3_column_int(stmt, count++); + record->suppress_reply_notifications = sqlite3_column_int(stmt, count++); + record->sync_event = sqlite3_column_int(stmt, count++); + record->times_cleaned = sqlite3_column_int(stmt, count++); + record->guests_can_modify = sqlite3_column_int(stmt, count++); + record->guests_can_invite_others = sqlite3_column_int(stmt, count++); + record->guests_can_see_guests = sqlite3_column_int(stmt, count++); + record->access_level = sqlite3_column_int(stmt, count++); + record->sync_status = sqlite3_column_int(stmt, count++); + record->is_deleted = sqlite3_column_int(stmt, count++); + record->account_id = sqlite3_column_int(stmt, count++); + record->sensitivity = sqlite3_column_int(stmt, count++); + record->store_type = sqlite3_column_int(stmt, count++); +} + +int cals_rearrage_calendar_field(const char *src, char *dest, int dest_size) +{ + int ret = 0; + if (strstr(src,CAL_TABLE_TXT_CALENDAR_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_CALENDAR_ID); + + if (strstr(src,CAL_TABLE_TXT_UID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_UID); + + if (strstr(src,CAL_TABLE_TXT_LINK)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_LINK); + + if (strstr(src,CAL_TABLE_INT_UPDATED)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_UPDATED); + + if (strstr(src,CAL_TABLE_TXT_NAME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_NAME); + + if (strstr(src,CAL_TABLE_TXT_DESCRIPTION)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_DESCRIPTION); + + if(strstr(src,CAL_TABLE_TXT_AUTHOR)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_AUTHOR); + + if(strstr(src,CAL_TABLE_TXT_COLOR)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_COLOR); + + if(strstr(src, CAL_TABLE_INT_HIDDEN)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_HIDDEN); + + if(strstr(src, CAL_TABLE_INT_SELECTED)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_SELECTED); + + if(strstr(src, CAL_TABLE_TXT_LOCATION)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_LOCATION); + + if(strstr(src, CAL_TABLE_INT_LOCALE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_LOCALE); + + if(strstr(src,CAL_TABLE_INT_COUNTRY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_COUNTRY); + + if(strstr(src,CAL_TABLE_INT_TIME_ZONE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_TIME_ZONE); + + if(strstr(src,CAL_TABLE_TXT_TIME_ZONE_LABEL)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_TIME_ZONE_LABEL); + + if(strstr(src,CAL_TABLE_INT_DISPLAY_ALL_TIMEZONES)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_DISPLAY_ALL_TIMEZONES); + + if(strstr(src,CAL_TABLE_INT_DATE_FIELD_ORDER)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_DATE_FIELD_ORDER); + + if(strstr(src,CAL_TABLE_INT_FROMAT_24HOUR_TIME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_FROMAT_24HOUR_TIME); + + if(strstr(src,CAL_TABLE_INT_WEEK_START)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_WEEK_START); + + if(strstr(src,CAL_TABLE_INT_DEFAULT_CAL_MODE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_DEFAULT_CAL_MODE); + + if(strstr(src,CAL_TABLE_INT_CUSTOM_CAL_MODE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_CUSTOM_CAL_MODE); + + if(strstr(src,CAL_TABLE_TXT_USER_LOCATION)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_USER_LOCATION); + + if(strstr(src,CAL_TABLE_TXT_WEATHER)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_TXT_WEATHER); + + if(strstr(src,CAL_TABLE_INT_SHOW_DECLINED_EVENTS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_SHOW_DECLINED_EVENTS); + + if(strstr(src,CAL_TABLE_INT_HIDE_INVITATIONS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_HIDE_INVITATIONS); + + if(strstr(src,CAL_TABLE_INT_ALTERNATE_CALENDAR)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_ALTERNATE_CALENDAR); + + if(strstr(src,CAL_TABLE_INT_VISIBILITY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_VISIBILITY); + + if(strstr(src,CAL_TABLE_INT_PROJECTION)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_PROJECTION); + + if(strstr(src,CAL_TABLE_INT_SEQUENCE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_SEQUENCE); + + if(strstr(src,CAL_TABLE_INT_SUPRESS_REPLY_NOTIFICATIONS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_SUPRESS_REPLY_NOTIFICATIONS); + + if(strstr(src, CAL_TABLE_INT_SYNC_EVENT)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_SYNC_EVENT); + + if(strstr(src,CAL_TABLE_INT_TIMES_CLEANED)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_TIMES_CLEANED); + + if(strstr(src,CAL_TABLE_INT_GUESTS_CAN_MODIFY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_GUESTS_CAN_MODIFY); + + if(strstr(src,CAL_TABLE_INT_GUESTS_CAN_INVITE_OTHERS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_GUESTS_CAN_INVITE_OTHERS); + + if(strstr(src,CAL_TABLE_INT_GUESTS_CAN_SEE_GUESTS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_GUESTS_CAN_SEE_GUESTS); + + if(strstr(src,CAL_TABLE_INT_ACCESS_LEVEL)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_ACCESS_LEVEL); + + if(strstr(src,CAL_TABLE_INT_SYNC_STATUS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_SYNC_STATUS); + + if(strstr(src,CAL_TABLE_INT_IS_DELETED)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_IS_DELETED); + + if(strstr(src,CAL_TABLE_INT_ACCOUNT_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_ACCOUNT_ID); + + if(strstr(src,CAL_TABLE_INT_SENSITIVITY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_SENSITIVITY); + + if(strstr(src, CAL_TABLE_INT_STORE_TYPE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_TABLE_INT_STORE_TYPE); + + return CAL_SUCCESS; +} + +int cals_stmt_get_filted_calendar(sqlite3_stmt *stmt, + calendar_t *record, const char *select_field) +{ + int count = 0; + const unsigned char *temp; + const char *start, *result; + + retv_if(NULL == stmt, CAL_ERR_ARG_NULL); + retv_if(NULL == record, CAL_ERR_ARG_NULL); + retv_if(NULL == select_field, CAL_ERR_ARG_NULL); + + record->index = sqlite3_column_int(stmt, count++); + + start = select_field; + if((result = strstr(start, CAL_TABLE_TXT_CALENDAR_ID))) { + temp = sqlite3_column_text(stmt, count++); + record->calendar_id = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_UID))) { + temp = sqlite3_column_text(stmt, count++); + record->uid = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_LINK))) { + temp = sqlite3_column_text(stmt, count++); + record->link = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_UPDATED))) { + record->updated = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_NAME))) { + temp = sqlite3_column_text(stmt, count++); + record->name = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_DESCRIPTION))) { + temp = sqlite3_column_text(stmt, count++); + record->description = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_AUTHOR))) { + temp = sqlite3_column_text(stmt, count++); + record->author = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_COLOR))) { + temp = sqlite3_column_text(stmt, count++); + record->color = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_HIDDEN))) { + record->hidden = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_SELECTED))) { + record->selected = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_LOCATION))) { + temp = sqlite3_column_text(stmt, count++); + record->location = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_LOCALE))) { + record->locale = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_COUNTRY))) { + record->country = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_TIME_ZONE))) { + record->time_zone = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_TIME_ZONE_LABEL))) { + temp = sqlite3_column_text(stmt, count++); + record->timezone_label = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_DISPLAY_ALL_TIMEZONES))) { + record->display_all_timezones = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_DATE_FIELD_ORDER))) { + record->date_field_order = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_FROMAT_24HOUR_TIME))) { + record->format_24hour_time = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_WEEK_START))) { + record->week_start = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_DEFAULT_CAL_MODE))) { + record->default_cal_mode = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_CUSTOM_CAL_MODE))) { + record->custom_cal_mode = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_USER_LOCATION))) { + temp = sqlite3_column_text(stmt, count++); + record->user_location = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_TXT_WEATHER))) { + temp = sqlite3_column_text(stmt, count++); + record->weather = SAFE_STRDUP(temp); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_SHOW_DECLINED_EVENTS))) { + record->show_declined_events = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_HIDE_INVITATIONS))) { + record->hide_invitations = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_ALTERNATE_CALENDAR))) { + record->alternate_calendar = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_VISIBILITY))) { + record->visibility = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_PROJECTION))) { + record->projection = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_SEQUENCE))) { + record->sequence = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_SUPRESS_REPLY_NOTIFICATIONS))) { + record->suppress_reply_notifications = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_SYNC_EVENT))) { + record->sync_event = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_TIMES_CLEANED))) { + record->times_cleaned = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_GUESTS_CAN_MODIFY))) { + record->guests_can_modify = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_GUESTS_CAN_INVITE_OTHERS))) { + record->guests_can_invite_others = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_GUESTS_CAN_SEE_GUESTS))) { + record->guests_can_see_guests = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_ACCESS_LEVEL))) { + record->access_level = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_SYNC_STATUS))) { + record->sync_status = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_IS_DELETED))) { + record->is_deleted = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_ACCOUNT_ID))) { + record->account_id = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_SENSITIVITY))) { + record->sensitivity = sqlite3_column_int(stmt, count++); + start = result; + } + if((result = strstr(start, CAL_TABLE_INT_STORE_TYPE))) { + record->store_type = sqlite3_column_int(stmt, count++); + start = result; + } + return CAL_SUCCESS; +} + diff --git a/src/cals-calendar.h b/src/cals-calendar.h new file mode 100755 index 0000000..ee75882 --- /dev/null +++ b/src/cals-calendar.h @@ -0,0 +1,34 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_CALENDAR_H__ +#define __CALENDAR_SVC_CALENDAR_H__ + +int cals_insert_calendar(const calendar_t *calendar); +int cals_update_calendar(const calendar_t *calendar_info); + +int cals_delete_calendars(int account_id); +int cals_delete_calendar(int index); + +int cals_rearrage_calendar_field(const char *src, char *dest, int dest_size); + +void cals_stmt_get_calendar(sqlite3_stmt *stmt, calendar_t *calendar_record); +int cals_stmt_get_filted_calendar(sqlite3_stmt *stmt, calendar_t *calendar_record, const char *select_field); + +#endif /* __CALENDAR_SVC_CALENDAR_H__ */ + diff --git a/src/cals-db.c b/src/cals-db.c new file mode 100755 index 0000000..414cdd7 --- /dev/null +++ b/src/cals-db.c @@ -0,0 +1,924 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include + +#include "cals-internal.h" +#include "calendar-svc-provider.h" +#include "calendar-svc-errors.h" +#include "cals-db-info.h" +#include "cals-typedef.h" +#include "cals-utils.h" +#include "cals-tz-utils.h" +#include "cals-ical.h" +#include "cals-recurrence-utils.h" +#include "cals-alarm.h" +#include "cals-sqlite.h" +#include "cals-schedule.h" +#include "cals-db.h" + +extern sqlite3 *calendar_db_handle; + +static bool __check_record_index_valid(int index) +{ + if ((index < 0) || (index >= (0x7fffffff)) ) + { + return false; + } + return true; +} + +/************************************************************************************************ + * * + * org engine init APIs * + * * + ************************************************************************************************/ + +bool cal_db_service_init_schedule_record(cal_sch_t *sch_record, int *error_code) +{ + time_t t = time(NULL); + tzset(); + struct tm *tm = NULL; //localtime(&t); + struct tm ttm; + + tm = localtime_r(&t,&ttm); + + if(NULL == tm) + { + return false; + } + struct tm temp_date_time = {0}; + struct tm current_time = {0}; + + retvm_if(NULL == error_code, false, "The error_code is NULL"); + + if(NULL == sch_record) { + ERR("The sch_record is NULL"); + *error_code = CAL_ERR_ARG_INVALID; + return false; + } + + memset(sch_record,0,sizeof(cal_sch_t)); + + sch_record->index = CAL_INVALID_INDEX; + sch_record->cal_type = CAL_EVENT_SCHEDULE_TYPE; + sch_record->sch_category = CAL_SCH_APPOINTMENT; + memset(&temp_date_time, 0 ,sizeof(struct tm)); + memset(&sch_record->start_date_time, 0 ,sizeof(struct tm)); + memset(&sch_record->end_date_time, 0 ,sizeof(struct tm)); + memset(&sch_record->repeat_end_date, 0 ,sizeof(struct tm)); + memset(&sch_record->alarm_time, 0 ,sizeof(struct tm)); + memcpy(¤t_time,tm,sizeof(struct tm)); + //CALS_DBG("!!!!!!!!!!!----------current hour is %d, minutes %d----------------",current_time.tm_hour,current_time.tm_min); + + memcpy(&sch_record->start_date_time,¤t_time,sizeof(struct tm)); + memcpy(&sch_record->alarm_time,¤t_time,sizeof(struct tm)); + memcpy(&sch_record->end_date_time,¤t_time,sizeof(struct tm)); + sch_record->start_date_time.tm_sec = 0; + sch_record->alarm_time.tm_sec = 0; + sch_record->end_date_time.tm_sec = 0; + sch_record->end_date_time.tm_hour ++; + if (sch_record->end_date_time.tm_hour > 23) + { + sch_record->end_date_time.tm_hour = 0; + cal_db_service_get_tomorrow(&sch_record->end_date_time); + } + + temp_date_time.tm_year = 137; + temp_date_time.tm_mon = 11; + temp_date_time.tm_mday = 31; + memcpy(&sch_record->repeat_end_date,&temp_date_time,sizeof(struct tm)); + + sch_record->remind_tick = CAL_INVALID_INDEX; //inintial + sch_record->repeat_term = CAL_REPEAT_NONE; + sch_record->day_date = 1; + sch_record->calendar_type = CAL_PHONE_CALENDAR; + return true; +} + +bool cal_db_service_free_participant(cal_participant_info_t* paritcipant_info, int *error_code) +{ + if(NULL == paritcipant_info) + { + return true; + } + + CAL_FREE(paritcipant_info->attendee_email); + CAL_FREE(paritcipant_info->attendee_number); + CAL_FREE(paritcipant_info->attendee_name); + + return true; +} + +bool cal_db_service_free_category(cal_category_info_t* category_info, int *error_code) +{ + if(NULL == category_info) + { + return true; + } + CAL_FREE(category_info->category_name); + return true; +} + + +bool cal_db_service_free_full_record(cal_sch_full_t *sch_full_record, int *error_code) +{ + retex_if(error_code == NULL, ,"error_code is NULL."); + retex_if(sch_full_record == NULL, *error_code = CAL_ERR_ARG_INVALID,"sch_full_record is NULL."); + cal_value *value = NULL; + GList *head; + + CAL_FREE(sch_full_record->summary); + CAL_FREE(sch_full_record->description); + CAL_FREE(sch_full_record->location); + CAL_FREE(sch_full_record->week_flag); + CAL_FREE(sch_full_record->uid); + CAL_FREE(sch_full_record->organizer_name); + CAL_FREE(sch_full_record->organizer_email); + CAL_FREE(sch_full_record->gcal_id); + CAL_FREE(sch_full_record->updated); + CAL_FREE(sch_full_record->location_summary); + CAL_FREE(sch_full_record->etag); + CAL_FREE(sch_full_record->edit_uri); + CAL_FREE(sch_full_record->gevent_id); + CAL_FREE(sch_full_record->tz_name); + CAL_FREE(sch_full_record->tz_city_name); + + if(sch_full_record->exception_date_list) + { + head = sch_full_record->exception_date_list; + while (sch_full_record->exception_date_list) + { + value = sch_full_record->exception_date_list->data; + if(value) + { + free(value->user_data); + free(value); + } + sch_full_record->exception_date_list = sch_full_record->exception_date_list->next; + } + g_list_free(head); + sch_full_record->exception_date_list = NULL; + } + + if (sch_full_record->attendee_list) + { + head = sch_full_record->attendee_list; + while (sch_full_record->attendee_list) + { + value = sch_full_record->attendee_list->data; + if(NULL != value) + { + if(NULL != value->user_data) + { + cal_db_service_free_participant((cal_participant_info_t*)value->user_data,error_code); + CAL_FREE(value->user_data); + + } + CAL_FREE(value); + } + sch_full_record->attendee_list = sch_full_record->attendee_list->next; + } + g_list_free(head); + sch_full_record->attendee_list = NULL; + } + + if (sch_full_record->meeting_category) + { + head = sch_full_record->meeting_category; + while (sch_full_record->meeting_category) + { + value = sch_full_record->meeting_category->data; + if(NULL != value) + { + if(NULL != value->user_data) + { + cal_db_service_free_category((cal_category_info_t*)value->user_data,error_code); + CAL_FREE(value->user_data); + } + CAL_FREE(value); + } + sch_full_record->meeting_category = sch_full_record->meeting_category->next; + } + g_list_free(head); + sch_full_record->meeting_category = NULL; + } + + return true; + +CATCH: + + return false; +} + + +bool cal_db_service_free_sch_record(cal_sch_t *sch_record, int *error_code) +{ + retex_if(error_code == NULL, ,"error_code is NULL."); + retex_if(sch_record == NULL, *error_code = CAL_ERR_ARG_INVALID,"sch_record is NULL."); + + CAL_FREE(sch_record->summary); + CAL_FREE(sch_record->description); + CAL_FREE(sch_record->location); + CAL_FREE(sch_record->week_flag); + + return true; + +CATCH: + + return false; +} + +/************************************************************************************************ + * * + * calendar event table add/edit APIs * + * * + ************************************************************************************************/ +bool cal_db_service_get_meeting_category_info_by_index(const int event_id, GList** record_list, int *error_code) +{ + int rc = -1; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + cal_category_info_t* category_info = NULL; + sqlite3_stmt *stmt = NULL; + cal_value *cvalue = NULL; + + retex_if(error_code == NULL, ,"cal_db_service_get_record_by_index: The error_code is NULL."); + + //check if db opened + retex_if(NULL == calendar_db_handle, *error_code = CAL_ERR_DB_NOT_OPENED, "The calendar database hasn't been opened."); + + sprintf(sql_value, "select * from cal_meeting_category_table where event_id = %d;", event_id); + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK, *error_code = CAL_ERR_DB_FAILED, "EDBStmtCreate error!!"); + + rc = sqlite3_step(stmt); + while(rc == SQLITE_ROW) + { + cvalue = (cal_value*)malloc(sizeof(cal_value)); + retex_if(NULL == cvalue,,"[ERROR]cal_db_service_get_participant_info_by_index:Failed to malloc!"); + + cvalue->v_type = CAL_EVENT_CATEGORY; + cvalue->user_data = category_info = (cal_category_info_t*)malloc(sizeof(cal_category_info_t)); + retex_if(category_info == NULL, *error_code = CAL_ERR_DB_FAILED, "cal_category_info_t malloc error!!"); + + memset(category_info,0x00,sizeof(cal_category_info_t)); + + category_info->event_id = sqlite3_column_int(stmt, 0); + + cal_db_get_text_from_stmt(stmt,&(category_info->category_name),1); + + *record_list = g_list_append(*record_list, (gpointer)cvalue); + + rc = sqlite3_step(stmt); + retex_if(SQLITE_ROW != rc && SQLITE_OK != rc && SQLITE_DONE != rc,*error_code = CAL_ERR_DB_FAILED,"__cal_db_service_get_meeting_category_info_by_index:Failed to query."); + } + + if(NULL != stmt) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return true; + +CATCH: + + if(cvalue){ + CAL_FREE(cvalue->user_data); + CAL_FREE(cvalue); + } + + if (stmt) + { + sqlite3_finalize(stmt); + stmt = NULL; + + } + + return false; +} + + +int cal_service_add_participant_info(const int event_id, const cal_participant_info_t* current_record) +{ + int ret = -1; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MAX_LEN]; + + //check if db opened + + sprintf(sql_value,"INSERT INTO %s(event_id,attendee_name,attendee_email,attendee_number,attendee_status,attendee_type,attendee_ct_index," + "attendee_role,attendee_rsvp,attendee_group,attendee_delegator_uri,attendee_delegate_uri,attendee_uid) " + "VALUES(%d, ?, ?, ?, %d, %d, %d,%d,%d,?,?,?,?)", CALS_TABLE_PARTICIPANT, + event_id, + current_record->attendee_status, + current_record->attendee_type, + current_record->attendee_ct_index, + current_record->attendee_role, + current_record->attendee_rsvp); + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + if (current_record->attendee_name) + cals_stmt_bind_text(stmt, 1, current_record->attendee_name); + + if (current_record->attendee_email) + cals_stmt_bind_text(stmt, 2, current_record->attendee_email); + + if (current_record->attendee_number) + cals_stmt_bind_text(stmt, 3, current_record->attendee_number); + + if (current_record->attendee_group) + cals_stmt_bind_text(stmt, 4, current_record->attendee_group); + + if (current_record->attendee_delegator_uri) + cals_stmt_bind_text(stmt, 5, current_record->attendee_delegator_uri); + + if (current_record->attendee_delegate_uri) + cals_stmt_bind_text(stmt, 6, current_record->attendee_delegate_uri); + + if (current_record->attendee_uid) + cals_stmt_bind_text(stmt, 7, current_record->attendee_uid); + + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", ret); + return ret; + } + sqlite3_finalize(stmt); + + return CAL_SUCCESS; +} + +/************************************************************************************************ + * * + * calendar event table get APIs * + * * + ************************************************************************************************/ + +bool cal_db_service_get_participant_info_by_index(const int panticipant_index, GList** record_list, int *error_code) +{ + int rc = -1; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + cal_participant_info_t* participant_info = NULL; + sqlite3_stmt *stmt = NULL; + cal_value *cvalue = NULL; + + retex_if(error_code == NULL, ,"cal_db_service_get_record_by_index: The error_code is NULL.\n"); + + //check input parameter + retex_if (!__check_record_index_valid(panticipant_index),*error_code = CAL_ERR_ARG_INVALID, "The index is invalid." ); + + //check if db opened + retex_if(NULL == calendar_db_handle, *error_code = CAL_ERR_DB_NOT_OPENED, "The calendar database hasn't been opened."); + + sprintf(sql_value, "select * from cal_participant_table where event_id = %d;", panticipant_index); + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK, *error_code = CAL_ERR_DB_FAILED, "Failed to get stmt!!"); + + rc = sqlite3_step(stmt); + retex_if(rc!= SQLITE_ROW && rc!= SQLITE_OK && rc!= SQLITE_DONE, *error_code = CAL_ERR_DB_FAILED, "[ERROR]cal_db_service_get_participant_info_by_index:Query error !!"); + while(rc == SQLITE_ROW) + { + cvalue = (cal_value*)malloc(sizeof(cal_value)); + retex_if(NULL == cvalue,,"[ERROR]cal_db_service_get_participant_info_by_index:Failed to malloc!\n"); + + cvalue->v_type = CAL_EVENT_PATICIPANT; + cvalue->user_data = (cal_participant_info_t*)malloc(sizeof(cal_participant_info_t)); + retex_if(NULL == cvalue->user_data,,"[ERROR]cal_db_service_get_participant_info_by_index:Failed to malloc!\n"); + + participant_info = cvalue->user_data; + memset(participant_info, 0x00, sizeof(cal_participant_info_t)); + + participant_info->event_id = sqlite3_column_int(stmt, 0); + + cal_db_get_text_from_stmt(stmt,&(participant_info->attendee_name),1); + cal_db_get_text_from_stmt(stmt,&(participant_info->attendee_email),2); + cal_db_get_text_from_stmt(stmt,&(participant_info->attendee_number),3); + participant_info->attendee_status = sqlite3_column_int(stmt, 4); + participant_info->attendee_type = sqlite3_column_int(stmt, 5); + participant_info->attendee_ct_index = sqlite3_column_int(stmt, 6); + participant_info->attendee_role = sqlite3_column_int(stmt, 7); + participant_info->attendee_rsvp = sqlite3_column_int(stmt, 8); + cal_db_get_text_from_stmt(stmt,&(participant_info->attendee_group),9); + cal_db_get_text_from_stmt(stmt,&(participant_info->attendee_delegator_uri),10); + cal_db_get_text_from_stmt(stmt,&(participant_info->attendee_delegate_uri),11); + cal_db_get_text_from_stmt(stmt,&(participant_info->attendee_uid),12); + + *record_list = g_list_append(*record_list, (gpointer)cvalue); + + cvalue = NULL; + + rc = sqlite3_step(stmt); + + if(rc == SQLITE_DONE) + { + break; + } + + retex_if(rc != SQLITE_ROW && rc != SQLITE_OK && rc != SQLITE_DONE, *error_code = CAL_ERR_DB_FAILED, "Query error!!"); + + } + //DBG("Get that\n"); + if (stmt) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return true; + +CATCH: + if (cvalue) + { + if (cvalue->user_data) + { + CAL_FREE(participant_info->attendee_name); + CAL_FREE(participant_info->attendee_email); + CAL_FREE(participant_info->attendee_number); + CAL_FREE(cvalue->user_data); + } + CAL_FREE(cvalue); + } + + if (stmt) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return false; +} + +bool cal_db_service_get_record_full_field_by_index(const int index, cal_sch_full_t *returned_record, int *error_code) +{ + int rc = -1; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + sqlite3_stmt *stmt = NULL; + + retex_if(error_code == NULL, ,"The error_code is NULL.\n"); + retex_if(returned_record == NULL, *error_code = CAL_ERR_ARG_INVALID,"The returned_record is NULL.\n"); + + //check input parameter + retex_if (!__check_record_index_valid(index),*error_code = CAL_ERR_ARG_INVALID,"The index is invalid." ); + + //check if db opened + retex_if(NULL == calendar_db_handle, *error_code = CAL_ERR_DB_NOT_OPENED, "The calendar database hasn't been opened."); + + sprintf(sql_value, "SELECT * FROM %s WHERE id = %d and is_deleted = 0;", CALS_TABLE_SCHEDULE, index); + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK, *error_code = CAL_ERR_DB_FAILED, "Failed to get stmt!!"); + + rc = sqlite3_step(stmt); + retex_if(rc != SQLITE_ROW && rc != SQLITE_OK && rc != SQLITE_DONE, *error_code = CAL_ERR_DB_FAILED, "Failed to query!!"); + + cals_stmt_get_full_schedule(stmt,returned_record,false); + + cal_db_service_get_participant_info_by_index(index, &(returned_record->attendee_list), error_code); + cal_db_service_get_meeting_category_info_by_index(index, &(returned_record->meeting_category), error_code); + + if(NULL!= stmt) + { + sqlite3_finalize(stmt); + stmt=NULL; + } + + //calendar_svc_end_trans(); + + return true; + +CATCH: + + if(NULL!= stmt) + { + sqlite3_finalize(stmt); + stmt=NULL; + } + + //calendar_svc_end_trans(); + + return false; +} + +int __cal_service_delete_all_records(const int account_id, const cal_event_type_t record_type) +{ + int ret = 0; + char query[CALS_SQL_MAX_LEN] = {0}; + + time_t current_time = time(NULL); + if(account_id) + { + switch (record_type) + { + case CAL_EVENT_NONE: + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld WHERE account_id = %d", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time,account_id); + break; + case CAL_EVENT_SCHEDULE_TYPE: + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld WHERE (type = 1 and account_id = %d)", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time,account_id); + break; + case CAL_EVENT_TODO_TYPE: + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld WHERE (type = 2 and account_id = %d)", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time,account_id); + break; + case CAL_EVENT_MEMO_TYPE: + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld WHERE (type = 3 and locked_flag = 0 and account_id = %d)", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time,account_id); + break; + default: + ERR("Unknown type(%d)", record_type); + return CAL_ERR_ARG_INVALID; + } + } + else + { + switch (record_type) + { + case CAL_EVENT_NONE: + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time); + break; + case CAL_EVENT_SCHEDULE_TYPE: + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld WHERE type = 1", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time); + break; + case CAL_EVENT_TODO_TYPE: + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld WHERE type = 2", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time); + break; + case CAL_EVENT_MEMO_TYPE: + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld WHERE (type = 3 and locked_flag = 0)", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time); + break; + default: + ERR("Unknown type(%d)", record_type); + return CAL_ERR_ARG_INVALID; + } + } + + ret = cals_begin_trans(); + retvm_if(CAL_SUCCESS != ret, ret, "cals_begin_trans() Failed(%d)", ret); + + if (CAL_EVENT_NONE == record_type || CAL_EVENT_SCHEDULE_TYPE == record_type) { + if (account_id) + cals_alarm_remove(CALS_ALARM_REMOVE_BY_ACC_ID, account_id); + else + cals_alarm_remove(CALS_ALARM_REMOVE_ALL, account_id); + } + + ret = cals_query_exec(query); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_query_exec() Failed(%d)", ret); + return ret; + } + cals_end_trans(true); + + if(CAL_EVENT_SCHEDULE_TYPE == record_type) + cals_notify(CALS_NOTI_TYPE_EVENT); + else + cals_notify(CALS_NOTI_TYPE_TODO); + + return CAL_SUCCESS; +} + + +/************************************************************************************************ + * * + * event exception table APIs * + * * + ************************************************************************************************/ + +int cal_service_add_exception_info(int event_id, cal_exception_info_t *exception_info, + const cal_sch_full_t *sch_record) +{ + int ret; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN]; + struct tm* recurrency_tm = &exception_info->exception_start_time; + time_t start_time = cals_mktime(recurrency_tm); + + DBG("next_start_tm [%s\n", ctime(&start_time)); + + sprintf(sql_value,"INSERT INTO %s(start_date_time,end_date_time,event_id,exception_event_id,updated) " + "VALUES(%ld, %ld, %d, %d, ?)", CALS_TABLE_RECURRENCY_LOG, + cals_mktime(recurrency_tm), + cals_mktime(recurrency_tm), + event_id, + exception_info->event_id); + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", ret); + return ret; + } + sqlite3_finalize(stmt); + + return CAL_SUCCESS; +} + + +int cals_insert_timezone(cal_timezone_t *timezone_info) +{ + int ret; + sqlite3_stmt *stmt; + char query[CALS_SQL_MAX_LEN]; + + retv_if(NULL == timezone_info, CAL_ERR_ARG_NULL); + + sprintf(query,"INSERT INTO %s(tz_offset_from_gmt ,standard_name, " + "std_start_month ,std_start_position_of_week ,std_start_day, " + "std_start_hour ,standard_bias ,day_light_name ,day_light_start_month, " + "day_light_start_position_of_week ,day_light_start_day, " + "day_light_start_hour ,day_light_bias) " + "VALUES(%d,?,%d,%d,%d,%d,%d,?,%d,%d,%d,%d,%d)", CALS_TABLE_TIMEZONE, + timezone_info->tz_offset_from_gmt, + timezone_info->std_start_month, + timezone_info->std_start_position_of_week, + timezone_info->std_start_day, + timezone_info->std_start_hour, + timezone_info->standard_bias, + timezone_info->day_light_start_month, + timezone_info->day_light_start_position_of_week, + timezone_info->day_light_start_day, + timezone_info->day_light_start_hour, + timezone_info->day_light_bias); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + if (timezone_info->standard_name) + cals_stmt_bind_text(stmt, 1, timezone_info->standard_name); + + if (timezone_info->day_light_name) + cals_stmt_bind_text(stmt, 2, timezone_info->day_light_name); + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", ret); + return ret; + } + ret = cals_last_insert_id(); + sqlite3_finalize(stmt); + + return ret; +} + + +int cals_update_timezone(cal_timezone_t *timezone_info) +{ + int ret; + sqlite3_stmt *stmt; + char query[CALS_SQL_MAX_LEN]; + + retv_if(NULL == timezone_info, CAL_ERR_ARG_NULL); + + sprintf(query, "UPDATE %s SET " + "tz_offset_from_gmt=%d," + "standard_name=?," + "std_start_month=%d," + "std_start_position_of_week=%d," + "std_start_day=%d," + "std_start_hour=%d," + "standard_bias=%d," + "day_light_name=?," + "day_light_start_month=%d," + "day_light_start_position_of_week=%d," + "day_light_start_day=%d," + "day_light_start_hour=%d," + "day_light_bias=%d " + "WHERE rowid = %d", + CALS_TABLE_TIMEZONE, + timezone_info->tz_offset_from_gmt, + timezone_info->std_start_month, + timezone_info->std_start_position_of_week, + timezone_info->std_start_day, + timezone_info->std_start_hour, + timezone_info->standard_bias, + timezone_info->day_light_start_month, + timezone_info->day_light_start_position_of_week, + timezone_info->day_light_start_day, + timezone_info->day_light_start_hour, + timezone_info->day_light_bias, + timezone_info->index); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + if (timezone_info->standard_name) + cals_stmt_bind_text(stmt, 1, timezone_info->standard_name); + + if (timezone_info->day_light_name) + cals_stmt_bind_text(stmt, 2, timezone_info->day_light_name); + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", ret); + return ret; + } + sqlite3_finalize(stmt); + + return CAL_SUCCESS; +} + + +/************************************************************************************************ + * * + * Recurrence exception API for activesync. * + * * + ************************************************************************************************/ + bool +cal_db_service_get_recurrency_exception(const int event_id, GList **exception_list, int *error_code) +{ + int rc = -1; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + sqlite3_stmt *stmt = NULL; + cal_exception_info_t* exception_info = NULL; + cal_value * cvalue = NULL; + retex_if(error_code == NULL, ,"cal_db_service_get_recurrency_exception_for_acs: The error_code is NULL.\n"); + retex_if (!__check_record_index_valid(event_id),*error_code = CAL_ERR_ARG_INVALID, "The index is invalid." ); + + sprintf(sql_value, "select start_date_time, exception_event_id from recurrency_log_table where event_id=%d;", event_id); + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK, *error_code = CAL_ERR_DB_FAILED, "Failed to get stmt!!"); + + rc = sqlite3_step(stmt); + retex_if(rc == SQLITE_DONE, *error_code = CAL_ERR_DB_FAILED, "cal_db_service_get_recurrency_exception no result!!"); + retex_if(rc != SQLITE_ROW, *error_code = CAL_ERR_DB_FAILED, "Query error!!"); + + while (rc == SQLITE_ROW) + { + cvalue = (cal_value*)malloc(sizeof(cal_value)); + retex_if(NULL == cvalue,,"Failed to malloc!\n"); + + cvalue->v_type = CAL_EVENT_RECURRENCY; + + cvalue->user_data = exception_info = (cal_exception_info_t*)malloc(sizeof(cal_exception_info_t)); + retex_if(NULL == exception_info,,"Failed to malloc!\n"); + + memset(exception_info, 0x00, sizeof(cal_exception_info_t)); + + time_t temp_time = sqlite3_column_int(stmt, 0); + //cal_db_service_copy_struct_tm((struct tm*)gmtime(&temp_time),&(exception_info->exception_start_time)); + gmtime_r(&temp_time,&(exception_info->exception_start_time)); + + exception_info->event_id = sqlite3_column_int(stmt, 1); + // exception_info->index = exception_event_id; + /* + if(exception_event_id != CAL_INVALID_INDEX) + { + sch_record = (cal_sch_full_t*)malloc(sizeof(cal_sch_full_t)); + cals_init_full_record(sch_record, error_code); + cal_db_service_get_record_full_field_by_index(exception_event_id,"exception",sch_record, error_code); + exception_info->exception_record = sch_record; + INFO( "Exception record is here : %d !!\n", exception_event_id); + } + else*/ + { + exception_info->exception_record = NULL; + } + + *exception_list = g_list_append(*exception_list, (gpointer)cvalue); + + rc = sqlite3_step(stmt); + if(rc == SQLITE_DONE) + { + break; + } + retex_if(rc != SQLITE_ROW, *error_code = CAL_ERR_DB_FAILED, "Query error!!"); + + + } + + CALS_DBG( "exception_info_length = %d\n", g_list_length(*exception_list)); + + /*if(g_list_length(*exception_list)>0) + { + time_t temp_time = mktime(&(exception_info->exception_start_time)); + //DBG("exception_start_time [%s\n", ctime(&temp_time)); + }*/ + + + if(NULL!= stmt) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + return true; + +CATCH: + if (cvalue) + { + CAL_FREE(cvalue->user_data); + CAL_FREE(cvalue); + } + if(NULL!= stmt) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return false; +} + + +int cal_db_service_get_month_event(int account_id, time_t startdate, time_t enddate,int is_repeat, sqlite3_stmt** stmt) +{ + + char condition[1024] = {0}; + char select_value[1024] = {0}; + char from_vlaue[1024] = {0}; + char sql_value[1024] = {0}; + time_t gm_startdate = 0; + time_t gm_enddate =0; + + calendar_svc_util_local_to_gmt(startdate,&gm_startdate); + calendar_svc_util_local_to_gmt(enddate,&gm_enddate); + + gm_startdate = gm_startdate - SECSPERDAY; + gm_enddate = gm_enddate + SECSPERDAY; + + if(account_id == ALL_VISIBILITY_ACCOUNT) + { + sprintf(from_vlaue,"from schedule_table as st, calendar_table as ct "\ + "where st.calendar_id = ct.rowid and ct.visibility = 1 "\ + "and "); + } + else + { + sprintf(from_vlaue,"from schedule_table as st where st.account_id = %d and ",account_id); + } + + if(is_repeat == FALSE) + { + sprintf(select_value,"select st.id, "\ + "st.all_day_event, "\ + "st.start_date_time, "\ + "st.end_date_time "); + + sprintf(condition, "st.type=%d and st.is_deleted = 0 "\ + "and (st.repeat_item = 0 and st.start_date_time <= %d and st.end_date_time >=%d) ", + CAL_EVENT_SCHEDULE_TYPE,(int)gm_enddate,(int)gm_startdate); + } + else + { + sprintf(select_value,"select st.id, "\ + "st.all_day_event, "\ + "st.start_date_time, "\ + "st.end_date_time, "\ + "st.repeat_item, "\ + "st.repeat_interval, "\ + "st.repeat_occurrences, "\ + "st.repeat_end_date, "\ + "st.week_start, "\ + "st.week_flag, "\ + "st.day_date, "\ + "st.timezone, "\ + "st.tz_name "); + + sprintf(condition, "st.type=%d and st.is_deleted = 0 "\ + "and (st.repeat_item>0 and st.repeat_end_date>=%d) ", + CAL_EVENT_SCHEDULE_TYPE,(int)gm_startdate ); + } + + sprintf(sql_value,"%s %s %s",select_value,from_vlaue,condition); + + *stmt = cals_query_prepare(sql_value); + retvm_if(NULL == *stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + return CAL_SUCCESS; +} diff --git a/src/cals-db.h b/src/cals-db.h new file mode 100755 index 0000000..019b792 --- /dev/null +++ b/src/cals-db.h @@ -0,0 +1,105 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +/** + * @ingroup app_engine + * @defgroup app_cal_engine Organizer + * @{ + */ + +#ifndef __CALENDAR_SVC_DB_H__ +#define __CALENDAR_SVC_DB_H__ + +#include +#include + +#include "cals-typedef.h" + +/** + * This function initialize schedule record. + * + * @return This function returns initialized record. + * @param[out] sch_record Points the field information for schedule table' s record. + * @param[out] error_code Points the error code. + * @exception None. + */ +bool cal_db_service_init_schedule_record(cal_sch_t *sch_record, int *error_code); + +/** + * This function free full schedule record. + * + * @return This function returns initialized record. + * @param[in] sch_full_record Points the field information for schedule table' s record. + * @param[out] error_code Points the error code. + * @exception CAL_ERR_ARG_INVALID. + */ +bool cal_db_service_free_full_record(cal_sch_full_t *sch_full_record, int *error_code); + + +/** + * This function gets the participant info by participant id from the specified table. + * + * @return This function returns true on success, or false on failure. + * @param[in] panticipant_index participant id from org table. + * @param[out] record_list records of this particapant info. + * @param[out] error_code Points the error code. + * @exception CAL_ERR_DB_NOT_OPENED, CAL_ERR_ARG_INVALID, CAL_ERR_DB_FAILED + */ +bool cal_db_service_get_participant_info_by_index(const int panticipant_index, GList** record_list, int *error_code); + +bool cal_db_service_get_meeting_category_info_by_index(const int event_id, GList** record_list, int *error_code); + +/** + * This function get record by index base on table type. + * + * @return This function returns true on success, or false on failure. + * @param[in] index specified the index. + * @param[out] returned_record Points of the full field information for schedule table' s record. + * @param[out] error_code Points the error code. + * @exception CAL_ERR_DB_NOT_OPENED, CAL_ERR_DB_FAILED, + * CAL_ERR_DB_RECORD_NOT_FOUND, CAL_ERR_DB_FAILED + */ +bool cal_db_service_get_record_full_field_by_index(const int index, cal_sch_full_t *returned_record, int *error_code); + +/** + * This function adds the participant info into the specified table. + * + * @return This function returns true on success, or false on failure. + * @param[in] participant_id participant id from org table. + * @param[in] current_record records of this particapant info. + * @param[out] error_code Points the error code. + * @exception CAL_ERR_DB_NOT_OPENED, CAL_ERR_ARG_INVALID, CAL_ERR_DB_FAILED + */ +int cal_service_add_participant_info(const int participant_id, const cal_participant_info_t* current_record); + +int cal_service_add_exception_info(int event_id, cal_exception_info_t *exception_info, const cal_sch_full_t *sch_record); + +int cal_db_service_get_month_event (int account_id, time_t startdate, time_t enddate,int is_repeat, sqlite3_stmt** stmt); + +int cals_insert_timezone(cal_timezone_t *timezone_info); +int cals_update_timezone(cal_timezone_t *timezone_info); + +bool cal_db_service_get_recurrency_exception(const int event_id, GList **exception_list, int *error_code); + +int __cal_service_delete_all_records(const int account_id, const cal_event_type_t record_type); + +/** + * @} + */ + +#endif /* __CALENDAR_SVC_DB_H__ */ diff --git a/src/cals-event.c b/src/cals-event.c new file mode 100755 index 0000000..9009382 --- /dev/null +++ b/src/cals-event.c @@ -0,0 +1,148 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-sqlite.h" +#include "cals-db-info.h" +#include "cals-db.h" +#include "cals-alarm.h" +#include "cals-utils.h" + +static inline void cals_event_make_condition(int calendar_id, + time_t start_time, time_t end_time, cal_sch_category_t category, int all_day, char *dest, int dest_size) +{ + int ret; + + ret = snprintf(dest, dest_size, "type = %d", CAL_EVENT_SCHEDULE_TYPE); + + if (calendar_id) + ret += snprintf(dest+ret, dest_size-ret, "AND calendar_id = %d", calendar_id); + + if (0 < start_time) + ret += snprintf(dest+ret, dest_size-ret, "AND start_date_time >= %ld", start_time); + + if (0 < end_time) + ret += snprintf(dest+ret, dest_size-ret, "AND start_date_time <= %ld", end_time); + + if (0 < category) + ret += snprintf(dest+ret, dest_size-ret, "AND category = %d", category); + + if (0 <= all_day) + ret += snprintf(dest+ret, dest_size-ret, "AND all_day_event = %d", !!(all_day)); +} + + +/** + * This function gets count related with event. + * If parameter is invalid(0, negative, etc.), it will be ignored + * If all parameters are invalid, this function return all event count. + * + * @param[in] calendar_id calendar_id + * @param[in] start_time start time + * @param[in] end_time end time + * @param[in] category #cal_sch_category_t + * @param[in] all_day TRUE(1 or positive)/FALSE(0)/IGNORE(-1 or negative) + * @return The count number on success, Negative value(#cal_error) on error + */ +API int calendar_svc_event_get_count(int calendar_id, + time_t start_time, time_t end_time, cal_sch_category_t category, int all_day) +{ + char query[CALS_SQL_MIN_LEN]; + char cond[CALS_SQL_MIN_LEN]; + + cals_event_make_condition(calendar_id, start_time, end_time, category, all_day, + cond, sizeof(cond)); + + snprintf(query, sizeof(query), "SELECT COUNT(*) FROM %s WHERE is_deleted = 0 AND %s", + CALS_TABLE_SCHEDULE, cond); + + return cals_query_get_first_int_result(query); +} + + +API cal_iter* calendar_svc_event_get_list(int calendar_id, + time_t start_time, time_t end_time, cal_sch_category_t category, int all_day) +{ + cal_iter *iter; + sqlite3_stmt *stmt = NULL; + char query[CALS_SQL_MAX_LEN]; + char cond[CALS_SQL_MIN_LEN]; + + cals_event_make_condition(calendar_id, start_time, end_time, category, all_day, + cond, sizeof(cond)); + + sprintf(query,"SELECT * FROM %s WHERE is_deleted = 0 AND %s ORDER BY start_date_time", + CALS_TABLE_SCHEDULE, cond); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, NULL,"cals_query_prepare() Failed"); + + iter = calloc(1, sizeof(cal_iter)); + if (NULL == iter) { + sqlite3_finalize(stmt); + ERR("calloc() Failed(%d)", errno); + return NULL; + } + iter->i_type = CAL_STRUCT_TYPE_SCHEDULE; + iter->stmt = stmt; + + return CAL_SUCCESS; +} + +API int calendar_svc_event_delete_all(int calendar_id) +{ + int ret; + char query[CALS_SQL_MAX_LEN] = {0}; + + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld " + "WHERE type = %d and calendar_id = %d", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED, time(NULL), + CAL_EVENT_SCHEDULE_TYPE, calendar_id); + + ret = cals_begin_trans(); + retvm_if(CAL_SUCCESS != ret, ret, "cals_begin_trans() Failed(%d)", ret); + + ret = cals_alarm_remove(CALS_ALARM_REMOVE_BY_CALENDAR_ID, calendar_id); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_alarm_remove() Failed(%d)", ret); + return ret; + } + + ret = cals_query_exec(query); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_query_exec() Failed(%d)", ret); + return ret; + } + cals_end_trans(true); + + cals_notify(CALS_NOTI_TYPE_EVENT); + + return CAL_SUCCESS; +} + +API cal_iter* calendar_svc_event_get_updated_list(int calendar_id, time_t timestamp) +{ + return cals_get_updated_list(CAL_EVENT_SCHEDULE_TYPE, calendar_id, timestamp); +} + + diff --git a/src/cals-ical-codec.c b/src/cals-ical-codec.c new file mode 100755 index 0000000..d9e758d --- /dev/null +++ b/src/cals-ical-codec.c @@ -0,0 +1,3764 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include + +#include "cals-typedef.h" +#include "cals-ical.h" +#include "cals-ical-codec.h" +#include "cals-utils.h" +#include "cals-db.h" +#include "cals-internal.h" +#include "cals-struct.h" + + +#define VCALENDAR_HEADER "BEGIN:VCALENDAR" +#define VNOTE_HEADER "BEGIN:VNOTE" + +#define MAX_BUFFER_SIZE 200 + + +/****************************************************************************************************/ +/* GLOBAL VARIABLE DECLARATION AND INITIALIZATION */ +/****************************************************************************************************/ +#define MAX_CAL_TYPE_NAME 50 + +/* Type */ +const char *pszCalTypeList[] = +{ + "AALARM", + "ACTION", + "ATTACH", + "ATTENDEE", + "BEGIN", + "CALSCALE", + "CATEGORIES", + "CLASS", + "COMMENT", + "COMPLETED", + "CONTACT", + "CREATED", + "DALARM", + "DAYLIGHT", + "DCREATED", + "DESCRIPTION", + "DTEND", + "DTSTAMP", + "DTSTART", + "DUE", + "DURATION", + "END", + "EXDATE", + "EXRULE", + "FREEBUSY", + "GEO", + "LAST-MODIFIED", + "LOCATION", + "MALARM", + "METHOD", + "ORGANIZER", + "PALARM", + "PERCENT-COMPLETE", + "PRIORITY", + "PRODID", + "RDATE", + "RECURRENCE-ID", + "RELATED-TO", + "REPEAT", + "REQUEST-STATUS", + "RESOURCES", + "RNUM", + "RRULE", + "SEQUENCE", + "STANDARD", + "STATUS", + "SUMMARY", + "TRANSP", + "TRIGGER", + "TZ", + "TZID", + "TZNAME", + "TZOFFSETFROM", + "TZOFFSETTO", + "TZURL", + "URL", + "UID", + "VALARM", + "VCALENDAR", + "VERSION", + "VEVENT", + "VFREEBUSY", + "VJOURNAL", + "VTIMEZONE", + "VTODO", + "X-FUNAMBOL-ALLDAY" +}; + +/* Parameter */ +static const char *pszCalParamList[] = +{ + "ALTREP", + "CHARSET", + "CN", + "CONTEXT", + "CUTYPE", + "DELEGATED-FROM", + "DELEGATED-TO", + "DIR", + "ENCODING", + "EXPECT", + "FBTYPE", + "FMTYPE", + "LANGUAGE", + "MEMBER", + "PARTSTAT", + "RANGE", + "RELATED", + "RELTYPE", + "ROLE", + "RSVP", + "SENT_BY", + "STATUS", + "TYPE", + "TZID", + "VALUE" +}; + +/* Cu type value */ +static const ValueObj pCalCutypeValList[] = +{ + {"GROUP", 0x00000001}, + {"INDIVIDUAL", 0x00000002}, + {"RESOURCE", 0x00000004}, + {"ROOM", 0x00000008}, + {"UNKNOWN", 0x00000010} +}; + +/* Character set value */ +static const ValueObj pCalCharsetValList[] = +{ + {"UTF-8", 0x00000001}, + {"UTF-16", 0x00000002} +}; + +/* Encoding value */ +static const ValueObj pCalEncValList[] = +{ + {"B", 0x00000001}, + {"BASE64", 0x00000002}, + {"QUOTED-PRINTABLE", 0x00000004}, + {"7BIT", 0x00000008}, + {"8BIT", 0x00000010} +}; + +/* Fb type value */ +static const ValueObj pCalFbtypeValList[] = +{ + {"BUSY", 0x00000001}, + {"BUSY_TENTATIVE", 0x00000002}, + {"BUSY_UNAVAILABLE", 0x00000004}, + {"FREE", 0x00000008} +}; + +/* Partstat value */ +static const ValueObj pCalPartstatValList[] = +{ + {"ACCEPTED", 0x00000001}, + {"COMPLETED", 0x00000002}, + {"DELEGATED", 0x00000004}, + {"DECLINED", 0x00000008}, + {"IN_PROCESS", 0x00000010}, + {"NEED_ACTION", 0x00000020}, + {"TENTATIVE", 0x00000040} +}; + +/* Range value */ +static const ValueObj pCalRangeValList[] = +{ + {"THISANDFUTURE", 0x00000001}, + {"THISANDPRIOR", 0x00000002} +}; + +/* Related value */ +static const ValueObj pCalRelatedValList[] = +{ + {"END", 0x00000001}, + {"START", 0x00000002} +}; + +/* Rel type value */ +static const ValueObj pCalReltypeValList[] = +{ + {"CHILD", 0x00000001}, + {"PARENT", 0x00000002}, + {"SIBLING", 0x00000004} +}; + +/* Value value */ +static const ValueObj pCalValValList[] = +{ + {"BINARY", 0x00000001}, + {"BOOLEAN", 0x00000002}, + {"CAL-ADDRESS", 0x00000004}, + {"CID", 0x00000008}, + {"CONTENT-ID", 0x00000010}, + {"DATE", 0x00000020}, + {"DATE-TIME", 0x00000040}, + {"DURATION", 0x00000080}, + {"FLOAT", 0x00000100}, + {"INTEGER", 0x00000200}, + {"PERIOD", 0x00000400}, + {"PHONE-NUMBER", 0x00000800}, + {"RECUR", 0X00001000}, + {"TEXT", 0x00002000}, + {"TIME", 0x00004000}, + {"URI", 0x00008000}, + {"URL", 0x00010000}, + {"UTC-OFFSET", 0x00020000}, + {"VCALENDAR", 0x00040000}, + {"VEVENT", 0x00080000}, + {"VTODO", 0x00100000} +}; + +/* Type value */ +static const ValueObj pCalTypeValList[] = +{ + {"AIFF", 0x00000001}, + {"BBS", 0x00000002}, + {"CAR", 0x00000004}, + {"CELL", 0x00000008}, + {"DOM", 0x00000010}, + {"FAX", 0x00000020}, + {"GIF", 0x00000040}, + {"HOME", 0x00000080}, + {"INTL", 0x00000100}, + {"INTERNET", 0x00000200}, + {"ISDN", 0x00000400}, + {"JPEG", 0x00000800}, + {"MODEM", 0x00001000}, + {"MSG", 0x00002000}, + {"PAGER", 0x00004000}, + {"PARCEL", 0x00008000}, + {"PCM", 0x00010000}, + {"PCS", 0x00020000}, + {"PNG", 0x00040000}, + {"POSTAL", 0x00080000}, + {"PREF", 0x00100000}, + {"VCARD", 0x00200000}, + {"VIDEO", 0x00400000}, + {"VOICE", 0x00800000}, + {"WAVE", 0x01000000}, + {"WBMP", 0x02000000}, + {"WORK", 0x04000000}, + {"X400", 0x08000000} +}; + +/* Expect value */ +static const ValueObj pCalExpectValList[] = +{ + {"FYI", 0x00000001}, + {"IMMEDIATE", 0x00000002}, + {"REQUEST", 0x00000004}, + {"REQUIRE", 0x00000008} +}; + +/* Role value */ +static const ValueObj pCalRoleValList[] = +{ + {"ATTENDEE", 0x00000001}, + {"CHAIR", 0x00000002}, + {"DELEGATE", 0x00000004}, + {"NON_PARTICIPANT", 0x00000008}, + {"OPT_PARTICIPANT", 0x00000010}, + {"ORGANIZER", 0x00000020}, + {"OWNER", 0x00000040}, + {"REQ_PARTICIPANT", 0x00000080} +}; + +/* RSVP value */ +static const ValueObj pCalRSVPValList[] = +{ + {"false", 0x00000001}, + {"NO", 0x00000002}, + {"true", 0x00000004}, + {"YES", 0x00000008} +}; + +/* Status value */ +static const ValueObj pCalStatusValList[] = +{ + {"ACCEPTED", 0x00000001}, + {"COMPLETED", 0x00000002}, + {"CONFIRMED", 0x00000004}, + {"DECLINED", 0x00000008}, + {"DELEGATED", 0x00000010}, + {"NEEDS ACTION", 0x00000020}, + {"SENT", 0x00000040}, + {"TENTATIVE", 0x00000080}, +}; + +/****************************************************************************************************/ +/* FUNCTION DECLARATION */ +/****************************************************************************************************/ +static int __VCalGetName( char*, char**, int ); +static int __VCalGetValue( char*, const ValueObj*, int ); +static int __VCalGetTypeName( char*, int*, int *); +static int __VCalGetParamName( char*, int*, int *); +static char* __VCalGetParamValue( char*, int*, int *); +static char* __VCalGetTypeValue( char*, int*, int*, int, VObject* ); +static char* __VCalParamEncode( VObject*, int *); + + +/* + * VIsVCalFile() verify VCalendar file. + * + * @param pVCalRaw Data which will be encoded + * @return int result (TRUE or FALSE) + */ +static int __VIsVCalFile(char *pVCalRaw) +{ + char *pszVCalBegin = "BEGIN:VCALENDAR"; + char *pszVCalEnd = "END:VCALENDAR"; + + /*for(i=0; i<15; i++) + { + if(*pszVCalBegin++ != *pVCalRaw++) + return false; + }*/ + + DBG("raw data:%s",pVCalRaw); + if( strstr(pVCalRaw, pszVCalBegin) == NULL) + return false; + + if( strstr(pVCalRaw, pszVCalEnd) == NULL) + return false; + return true; +} + + + +/* + * vCalFindName() compares the string and VCal type, parameter name. + * + * @param string Name which will compare + * @param list[] Name list of VCal type and param + * @param size Number of total element of list + * @return index The index in the list + */ +static int __VCalGetName( char *szString, char** pszList, int size ) +{ + int high, low, i, diff; + + DBG( "__VCalGetName() enter..\n"); + + + for ( low = 0, high = size - 1; high >= low; diff < 0 ? ( low = i+1 ) : ( high = i-1 ) ) + { + i = ( low + high ) / 2; + diff = strcmp( pszList[i], szString ); + if ( diff == 0 ) /* success: found it */ + return i; + } + return UNKNOWN_NAME; +} + + +/* + * vCalFindValue() compares the string and VCal type, parameter value. + * + * @param string Value which will compare + * @param list[] Value list of VCal type and param + * @param size Number of total element of list + * @return index The index in the list + */ +static int __VCalGetValue( char *szString, const ValueObj pList[], int size ) +{ + int high, low, i, diff; + char* szTemp = szString; + unsigned int k; + + DBG( "__VCalGetValue enter()..\n"); + + for ( k = 0; k < strlen( szTemp ); k++ ) + { + szTemp[k] = toupper( szTemp[k] ); + } + + for ( low = 0, high = size - 1; high >= low; diff < 0 ? ( low = i+1 ) : ( high = i-1 ) ) + { + i = ( low + high ) / 2; + diff = strcmp( pList[i].szName, szTemp ); + if ( diff == 0 ) /* success: found it */ + return pList[i].flag; + } + return UNKNOWN_NAME; +} + + +/* + * vCalTypeName() fine the type name and returns the index number + * + * @param pVCalRaw The raw data + * @param status Decoder status + * @return res The index in type list + */ +static int __VCalGetTypeName( char *pVCalRaw, int *pStatus, int *pDLen ) +{ + char name[MAX_CAL_TYPE_NAME]; + char c = VTYPE_TOKEN_SEMICOLON; + int res=UNKNOWN_NAME; + int i; + int index = 0; + + DBG( "__VCalGetTypeName() enter \n"); + + // while ( true ) + while ( pVCalRaw!= NULL ) + { + c = *pVCalRaw; + + pVCalRaw++; + ( *pDLen )++; + + if(index >= MAX_CAL_TYPE_NAME){ + DBG( "UNKNOWN_NAME!!(pVCalRaw(%s),%d)\n",pVCalRaw,index); + res = UNKNOWN_NAME; + if ( ( c == VTYPE_TOKEN_SEMICOLON ) || ( c == VTYPE_TOKEN_COLON ) ) + break; + //return UNKNOWN_NAME; + } + else + { + if ( ( c == VTYPE_TOKEN_SEMICOLON ) || ( c == VTYPE_TOKEN_COLON ) ) + { + name[index] = '\0'; + _VRLSpace( name ); + _VRTSpace( name ); + for ( i = 0; i < index; i++ ) + name[i] = toupper( name[i] ); + + res = __VCalGetName( name, ( char** )pszCalTypeList, VCAL_TYPE_NUM ); + break; + } + else if ( ( c == '\r' ) || ( c == '\n' ) || ( _VIsSpace( c ) ) ) ; + else + name[index++] = c; + } + } + + if ( c == VTYPE_TOKEN_SEMICOLON ) + *pStatus = VCAL_PARAM_NAME_STATUS; + else + *pStatus = VCAL_TYPE_VALUE_STATUS; + + DBG( "###########- __VCalGetTypeName() end..\n"); + + return res; +} + + +/* + * vCalParamName() fine the param name and returns the index number + * + * @param pVCalRaw The raw data + * @param status Decoder status + * @return res The index in param list + */ +static int __VCalGetParamName( char *pVCalRaw, int *pStatus, int *pDLen ) +{ + char name[50]; + char c; + int res; + int i; + int index = 0; + char* pTemp = pVCalRaw; + + DBG( "__VCalGetParamName() enter..\n"); + + // while ( true ) + while ( pVCalRaw!= NULL ) + { + c = *pVCalRaw; + pVCalRaw++; + ( *pDLen )++; + if ( c == VTYPE_TOKEN_EQUAL ) + { + name[index] = '\0'; + _VRLSpace( name ); + _VRTSpace( name ); + for ( i = 0; i < index; i++ ) + name[i] = toupper( name[i] ); + + res = __VCalGetName( name, ( char** )pszCalParamList, VCAL_PARAM_NUM ); + *pStatus = VCAL_PARAM_VALUE_STATUS; + return res; + } + else if ( c == VTYPE_TOKEN_COLON ) + { + *pStatus = VCAL_PARAM_VALUE_STATUS; + pVCalRaw = pTemp; + (*pDLen) = 0; + return UNKNOWN_NAME; + } + else if ( c == VTYPE_TOKEN_SEMICOLON ) + { + *pStatus = VCAL_PARAM_NAME_STATUS; + pVCalRaw = pTemp; + ( *pDLen ) = 0; + return UNKNOWN_NAME; + } + else if ( ( c == '\r' ) || ( c == '\n' ) || ( _VIsSpace( c ) ) ) ; + else + name[index++] = c; + } + return UNKNOWN_NAME; +} + + +/* + * vCalParamValue() fine the param value and returns value. + * + * @param pVCalRaw The raw data + * @param status Decoder status + * @return buffer The result value + */ +static char* __VCalGetParamValue( char *pVCalRaw, int *pStatus, int *pDLen ) +{ + char* pBuf = NULL; + char c; + int len = 0; + char* pTemp = pVCalRaw; + char buf[100]; + char delimiter; + + DBG( "__VCalGetParamValue() enter..\n"); + + // while ( true ) + while ( pVCalRaw!= NULL ) + { + c = *pVCalRaw; + pVCalRaw++; + ( *pDLen )++; + if ( c == VTYPE_TOKEN_SEMICOLON ) + { + buf[len] = '\0'; + if ( ( pBuf = ( char * )malloc( len+1 ) ) == NULL ) + { + DBG( "__VCalGetParamValue():malloc Failed\n"); + return NULL; + } + // memcpy( pBuf, pTemp, len-1 ); + strcpy( pBuf, buf ); + *( pBuf + len ) = '\0'; + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + *pStatus = VCAL_PARAM_NAME_STATUS; + return pBuf; + } + else if ( c == VTYPE_TOKEN_COLON ) + { + buf[len] = '\0'; + if ( ( pBuf = ( char * )malloc( len+1 ) ) == NULL ) + { + DBG( "__VCalGetParamValue():malloc Failed\n"); + return NULL; + } + // memcpy( pBuf, pTemp, len-1 ); + strcpy( pBuf, buf ); + *( pBuf + len ) = '\0'; + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + *pStatus = VCAL_TYPE_VALUE_STATUS; + return pBuf; + } + else if ( c == VTYPE_TOKEN_COMMA ) + { + buf[len] = '\0'; + if ( ( pBuf = ( char * )malloc( len+1 ) ) == NULL ) + { + DBG( "__VCalGetParamValue():malloc Failed\n"); + return NULL; + } + // memcpy( pBuf, pTemp, len-1 ); + strcpy( pBuf, buf ); + *( pBuf + len ) = '\0'; + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + *pStatus = VCAL_PARAM_VALUE_STATUS; + return pBuf; + } + else if ( c == VTYPE_TOKEN_QUOTE || c == VTYPE_TOKEN_DBLQUOTE ) + { + delimiter = c; + pTemp = pVCalRaw; + // while ( true ) + while ( pVCalRaw != NULL ) + { + c = *pVCalRaw; + pVCalRaw++; + ( *pDLen )++; + len++; + if ( c == delimiter ) + { + buf[len] = '\0'; + if ( ( pBuf = ( char * )malloc( len+1 ) ) == NULL ) + { + DBG( "__VCalGetParamValue():malloc Failed\n"); + return NULL; + } + // memcpy( pBuf, pTemp, len-1 ); + strcpy( pBuf, buf ); + *( pBuf + len ) = '\0'; + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + *pStatus = VCAL_PARAM_VALUE_STATUS; + //while ( true ) + while ( pVCalRaw != NULL ) + { + c = *pVCalRaw; + pVCalRaw++; + ( *pDLen )++; + len++; + if ( c == VTYPE_TOKEN_COLON ) break; + } + return pBuf; + } + buf[len++] = c; + } + } + else + buf[len++] = c; + } + return pBuf; +} + +int _gbase64Decode( char *Dest, char *Src ) +{ + gsize len; + + guchar *buf = g_base64_decode(Src,&len); + memcpy(Dest,buf,len); + g_free(buf); + DBG("_gbase64Decode before:\n%s \n",Src); + DBG("_gbase64Decode after:\n%s \n",Dest); + return len; +} + +void _gbase64Encode( char *Dest, char *Src, int len ) +{ + gchar *buf = g_base64_encode((guchar *)Src, strlen(Src)); + strcpy(Dest,buf); + DBG("_gbase64Decode before:\n%s \n",Src); + DBG("_gbase64Decode after:\n%s \n",Dest); + g_free(buf); +} + + +/* + * vCalTypeValue() fine the type value and returns value. + * + * @param VCalRaw The raw data + * @param status Decoder status + * @return buffer The result value + */ +static char* __VCalGetTypeValue( char *pVCalRaw, int *pStatus, int *pDLen, int enc, VObject* pType ) +{ + char* pBuf = NULL; + char c, c1, c2; + int len = 0; + char* pTemp = pVCalRaw; + char* pTmpBuf = NULL; + int bufferCount; + int num; + bool bEscape = false; + + DBG( "__VCalGetTypeValue() enter..\n"); + + // while ( true ) + while ( pVCalRaw!= NULL ) + { + c = *pVCalRaw; + pVCalRaw++; + ( *pDLen )++; + len++; + + if ( c == VTYPE_TOKEN_SEMICOLON && bEscape == false ) + { + if ( ( pBuf = ( char * )malloc( len ) ) == NULL ) + { + DBG( "__VCalGetTypeValue():malloc Failed\n"); + return NULL; + } + memcpy( pBuf, pTemp, len-1 ); + *( pBuf + len -1 ) = '\0'; + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + _VUnescape( pBuf ); + *pStatus = VCAL_TYPE_VALUE_STATUS; + if ( enc & pCalEncValList[1].flag ) + { + bufferCount = ( len * 6 / 8 ) + 2; + if ( ( pTmpBuf = ( char * )malloc( bufferCount ) ) == NULL ) + { + DBG( "__VCalGetTypeValue():malloc Failed\n"); + free(pBuf); + + return NULL; + } + memset( pTmpBuf, '\0', bufferCount ); + + num = _gbase64Decode( pTmpBuf, pBuf ); + + if ( pType != NULL ) + pType->numOfBiData = num; + free( pBuf ); + return pTmpBuf; + } + if ( enc & pCalEncValList[2].flag ) + { + int i = 0, j = 0; + + while ( pBuf[i] ) + { + if ( pBuf[i] == '\n' || pBuf[i] == '\r' ) + { + i++; + if ( pBuf[i] == '\n' || pBuf[i] == '\r' ) + i++; + + if ( pBuf[j-1] == '=' ) j--; + } + else + { + pBuf[j++] = pBuf[i++]; + } + } + pBuf[j] = '\0'; + + _VQPDecode( pBuf ); + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + } + return pBuf; + } + else if ( c == VTYPE_TOKEN_SEMICOLON && bEscape == true ) + { + bEscape = false; + } + else if ( c == '\\' ) + { + bEscape = true; + } + else if ( bEscape == true && c != VTYPE_TOKEN_SEMICOLON ) + { + bEscape = false; + } + else if ( ( c == '\r' ) || ( c == '\n' ) ) + { + c2 = *( pVCalRaw-2 ); + + if ( c2 == '=' && ( enc & pCalEncValList[2].flag ) ) + { + c1 = *pVCalRaw; + if ( ( c1 == '\r' ) || ( c1 == '\n' ) ) + { + pVCalRaw += 1; + ( *pDLen ) += 1; len++; + } + } + else + { + if ( ( pBuf = ( char * )malloc( len ) ) == NULL ) + { + DBG( "__VCalGetTypeValue():malloc Failed\n"); + return NULL; + } + + memcpy( pBuf, pTemp, len-1 ); + + *( pBuf + len -1 ) = '\0'; + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + _VUnescape( pBuf ); + *pStatus = VCAL_TYPE_NAME_STATUS; + + c1 = *( pVCalRaw ); + if ( ( c1 == '\r' ) || ( c1 == '\n' ) ) + { + pVCalRaw += 1; + ( *pDLen ) += 1; + } + + if ( enc & pCalEncValList[1].flag ) + { + + bufferCount = ( len * 6 / 8 ) + 2; + if ( ( pTmpBuf = ( char * )malloc( bufferCount ) ) == NULL ) + { + DBG( "__VCalGetTypeValue():malloc Failed\n"); + free(pBuf); + return NULL; + } + memset( pTmpBuf, '\0', bufferCount ); + len = _gbase64Decode( pTmpBuf, pBuf ); + if ( pType != NULL ) + pType->numOfBiData = len; + free( pBuf ); + return pTmpBuf; + } + if ( enc & pCalEncValList[2].flag ) + { + int i = 0, j = 0; + + while ( pBuf[i] ) + { + if ( pBuf[i] == '\n' || pBuf[i] == '\r' ) + { + i++; + if ( pBuf[i] == '\n' || pBuf[i] == '\r' ) + i++; + + if ( pBuf[j-1] == '=' ) j--; + } + else + { + pBuf[j++] = pBuf[i++]; + } + } + pBuf[j] = '\0'; + + _VQPDecode( pBuf ); + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + } + return pBuf; + } + + } + else if(enc == 0 && c == 0) // VCAlENDAR type value µðÄÚµù½Ã memory overlap µÇ´Â Çö»ó ¹æÁöÇϱâ À§ÇÑ ÄÚµå. + { + if ( ( pBuf = ( char * )malloc( len ) ) == NULL ) + { + DBG( "__VCalGetTypeValue():malloc Failed\n"); + return NULL; + } + memcpy( pBuf, pTemp, len-1 ); + *( pBuf + len -1 ) = '\0'; + _VQPDecode( pBuf ); + _VRLSpace( pBuf ); + _VRTSpace( pBuf ); + return pBuf; + } + } + DBG( "__VCalGetTypeValue() end..\n"); + + return pBuf; +} + + +/* + * vcal_decode() decode the VCal data and returns vObject struct + * + * @param pVCalRaw The raw data + * @return vObject The result value + */ + VTree* +vcal_decode( char *pVCalRaw ) +{ + char* szValue = NULL; + char c; + VParam* pTmpParam = NULL; + VTree* pRes = NULL; + VTree* pVCal = NULL; + VObject* pTemp = NULL; + VTree* pTmpTree = NULL; + char* szCalBegin = NULL; + char* szCalEnd = NULL; + int type, param; + int status = VCAL_TYPE_NAME_STATUS; + int done = false; + int valueCount = 0; + int len; + int dLen = 0; + int param_status = false; + int numberedParam = 0; + int enc = 0; + unsigned int i; + int diff; + + DBG( "------------------------------------------enter vcal_decode()--------------------------\n"); + + //SysRequireEx( pVCalRaw != NULL, NULL ); + retvm_if(NULL == pVCalRaw,NULL , "[ERROR]vcal_decode:Invalid parameter(pVCalRaw)!\n"); + + _VManyCRLF2CRLF(pVCalRaw); + + if(__VIsVCalFile(pVCalRaw) == false) // verify Vcalendar file + { + DBG( "not vcalendar file\n"); + return NULL; + } + + //len = _VUnfolding( pVCalRaw ); + len = _VUnfoldingNoSpec(pVCalRaw, VCALENDAR); + len = _VManySpace2Space( pVCalRaw ); + + if ( len < 10 ) + { + DBG("length is too short!!\n"); + return NULL; + } + + // while ( true ) + while ( pVCalRaw != NULL ) + { + + c = *pVCalRaw; + if ( ( c == '\0' ) || done ) + break; + + switch ( status ) + { + case VCAL_TYPE_NAME_STATUS: + enc = 0; + dLen = 0; + numberedParam = 0; + type = __VCalGetTypeName( pVCalRaw, &status, &dLen ); + pVCalRaw += dLen; + + switch ( type ) + { + case VCAL_TYPE_BEGIN: + DBG("VCAL_TYPE_BEGIN\n"); + dLen = 0; + pVCal = ( VTree* )malloc( sizeof( VTree ) ); + + if ( pVCal == NULL ) + { + DBG( "vcal_decode():malloc Failed\n"); + return NULL; + } + pVCal->pTop = NULL; + pVCal->pCur = NULL; + pVCal->pNext = NULL; + + szCalBegin = __VCalGetTypeValue( pVCalRaw, &status, &dLen, 0, NULL ); + + pVCalRaw += dLen; + + for ( i = 0; i < strlen( szCalBegin ); i++ ) + szCalBegin[i] = toupper( szCalBegin[i] ); + + if ( ( diff = strcmp( "VCALENDAR", szCalBegin ) ) == 0 ) + { + pVCal->treeType = VCALENDAR; + pRes = pVCal; + pTmpTree = pRes; + } + else if ( ( diff = strcmp( "VEVENT", szCalBegin ) ) == 0 ) + { + pVCal->treeType = VEVENT; + if(pTmpTree) + pTmpTree->pNext = pVCal; + pTmpTree = pVCal; + } + else if ( ( diff = strcmp( "VTODO", szCalBegin ) ) == 0 ) + { + pVCal->treeType = VTODO; + pTmpTree->pNext = pVCal; + pTmpTree = pVCal; + } + else if ( ( diff = strcmp( "VFREEBUSH", szCalBegin ) ) == 0 ) + { + pVCal->treeType = VFREEBUSY; + pTmpTree->pNext = pVCal; + pTmpTree = pVCal; + } + else if ( ( diff = strcmp( "VALARM", szCalBegin ) ) == 0 ) + { + pVCal->treeType = VALARM; + pTmpTree->pNext = pVCal; + pTmpTree = pVCal; + } + else if ( ( diff = strcmp( "VTIMEZONE", szCalBegin ) ) == 0 ) + { + pVCal->treeType = VTIMEZONE; + pTmpTree->pNext = pVCal; + pTmpTree = pVCal; + } + else if ( ( diff = strcmp( "VJOURNAL", szCalBegin ) ) == 0 ) + { + pVCal->treeType = VJOURNAL; + pTmpTree->pNext = pVCal; + pTmpTree = pVCal; + } + else if ( ( diff = strcmp( "STANDARD", szCalBegin ) ) == 0 ) + { + pVCal->treeType = STANDARD; + pTmpTree->pNext = pVCal; + pTmpTree = pVCal; + } + else if ( ( diff = strcmp( "DAYLIGHT", szCalBegin ) ) == 0 ) + { + pVCal->treeType = DAYLIGHT; + pTmpTree->pNext = pVCal; + pTmpTree = pVCal; + } + + free( szCalBegin ); + break; + case VCAL_TYPE_END: + dLen = 0; + DBG("VCAL_TYPE_END\n"); + szCalEnd = __VCalGetTypeValue( pVCalRaw, &status, &dLen, 0, NULL ); + + pVCalRaw += dLen; + + for ( i = 0; i < strlen( szCalEnd ); i++ ) + szCalEnd[i] = toupper(szCalEnd[i]); + + if ( ( diff = strcmp( "VCALENDAR", szCalEnd ) ) == 0 ) + done = true; + free( szCalEnd ); + + break; + //case UNKNOWN_NAME: + // DBG( "Unknown name!!\n"); + // break; + default: + + if ( pTmpTree == NULL ) + { + ERR( "vcal_decode():pTmpTree is NULL\n"); + vcal_free_vtree_memory(pVCal); + return NULL; + + } + + if ( ( pTemp = ( VObject* )malloc( sizeof( VObject ) ) ) == NULL ) + { + ERR( "vcal_decode():malloc Failed\n"); + vcal_free_vtree_memory(pVCal); + return NULL; + } + + memset( pTemp, 0, sizeof( VObject ) ); + pTemp->property = type; + + if ( pTmpTree->pTop == NULL ) + { + pTmpTree->pTop = pTemp; + pTmpTree->pCur = pTemp; + } + else + { + + pTmpTree->pCur->pSibling = pTemp; + pTmpTree->pCur = pTemp; + } + + break; + } + + numberedParam = 0; + param_status = false; + valueCount = 0; + break; + case VCAL_PARAM_NAME_STATUS: + dLen = 0; + param = __VCalGetParamName( pVCalRaw, &status, &dLen ); + pVCalRaw += dLen; + + if ( param_status != true ) + { + + if ( pTmpTree == NULL ) + { + return pVCal; + } + + if ( ( pTmpTree->pCur->pParam = ( VParam* )malloc( sizeof( VParam ) ) ) == NULL ) + { + DBG( "vcal_decode():malloc Failed\n"); + //SysSetLastError( VDATA_ERROR_MEMALLOC_FAILED ); + return pVCal; + } + param_status = true; + pTmpParam = pTmpTree->pCur->pParam; + memset( pTmpParam, 0, sizeof( VParam ) ); + } + else + { + if ( pTmpParam == NULL ) + { + return pVCal; + } + + if ( ( pTmpParam->pNext = ( VParam* )malloc( sizeof( VParam ) ) ) == NULL ) + { + DBG( "vcal_decode():malloc Failed\n"); + //SysSetLastError( VDATA_ERROR_MEMALLOC_FAILED ); + return pVCal; + } + pTmpParam = pTmpParam->pNext; + memset( pTmpParam, 0, sizeof( VParam ) ); + } + pTmpParam->parameter = param; + + // poiema Go through to the next case statement. + + case VCAL_PARAM_VALUE_STATUS: + dLen = 0; + numberedParam = 0; + if(pTmpParam == NULL) + break; + switch( pTmpParam->parameter ) + { + case VCAL_PARAM_TYPE: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalTypeValList, VCAL_TYPE_PARAM_NUM ); + break; + case VCAL_PARAM_VALUE: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalValValList, VCAL_VALUE_PARAM_NUM ); + break; + case VCAL_PARAM_ENCODING: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalEncValList, VCAL_ENCODE_PARAM_NUM ); + enc = numberedParam; + break; + case VCAL_PARAM_ROLE: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalRoleValList, VCAL_ROLE_PARAM_NUM ); + break; + case VCAL_PARAM_RSVP: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalRSVPValList, VCAL_RSVP_PARAM_NUM ); + break; + case VCAL_PARAM_EXPECT: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalExpectValList, VCAL_EXPECT_PARAM_NUM ); + break; + case VCAL_PARAM_STATUS: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalStatusValList, VCAL_STATUS_PARAM_NUM ); + break; + case VCAL_PARAM_CUTYPE: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalCutypeValList, VCAL_CUTYPE_PARAM_NUM ); + break; + case VCAL_PARAM_FBTYPE: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalFbtypeValList, VCAL_FBTYPE_PARAM_NUM ); + break; + case VCAL_PARAM_PARTSTAT: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalPartstatValList, VCAL_PARTSTAT_PARAM_NUM ); + break; + case VCAL_PARAM_RANGE: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalRangeValList, VCAL_RANGE_PARAM_NUM ); + break; + case VCAL_PARAM_RELATED: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalRelatedValList, VCAL_RELATED_PARAM_NUM ); + break; + case VCAL_PARAM_RELTYPE: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam |= __VCalGetValue( szValue, pCalReltypeValList, VCAL_RELTYPE_PARAM_NUM ); + break; + case VCAL_PARAM_CHARSET: + case VCAL_PARAM_CONTEXT: + case VCAL_PARAM_LANGUAGE: + case VCAL_PARAM_ALTREP: + case VCAL_PARAM_CN: + case VCAL_PARAM_DELEGATED_FROM: + case VCAL_PARAM_DELEGATED_TO: + case VCAL_PARAM_DIR: + case VCAL_PARAM_FMTYPE: + case VCAL_PARAM_MEMBER: + case VCAL_PARAM_SENT_BY: + case VCAL_PARAM_TZID: + { + char * pParamValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + if (pParamValue != NULL) + { + free(pParamValue); + pParamValue = NULL; + } + } + break; + + default: + szValue = __VCalGetParamValue( pVCalRaw, &status, &dLen ); + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalTypeValList, VCAL_TYPE_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_TYPE; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalValValList, VCAL_VALUE_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_VALUE; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalEncValList, VCAL_ENCODE_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_ENCODING; + enc = numberedParam; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalRoleValList, VCAL_ROLE_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_ROLE; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalRSVPValList, VCAL_RSVP_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_RSVP; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalExpectValList, VCAL_EXPECT_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_EXPECT; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalStatusValList, VCAL_STATUS_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_STATUS; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalCutypeValList, VCAL_CUTYPE_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_CUTYPE; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalFbtypeValList, VCAL_FBTYPE_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_FBTYPE; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalPartstatValList, VCAL_PARTSTAT_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_PARTSTAT; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalRangeValList, VCAL_RANGE_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_RANGE; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalRelatedValList, VCAL_RELATED_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_RELATED; + break; + } + numberedParam = 0; + numberedParam |= __VCalGetValue( szValue, pCalReltypeValList, VCAL_RELTYPE_PARAM_NUM ); + if ( numberedParam != UNKNOWN_NAME ) + { + pTmpParam->parameter = VCAL_PARAM_RELTYPE; + break; + } + numberedParam = 0; + + char * pTypeValue = __VCalGetTypeValue( pVCalRaw, &status, &dLen, 0, pVCal->pCur ); + if (pTypeValue != NULL) + { + free(pTypeValue); + pTypeValue = NULL; + } + + break; + } + pTmpParam->paramValue = numberedParam; + if (szValue != NULL) + { + free(szValue); + szValue = NULL; + } + pVCalRaw += dLen; + break; + + case VCAL_TYPE_VALUE_STATUS: + { + dLen = 0; + char *temp = NULL; + temp = __VCalGetTypeValue( pVCalRaw, &status, &dLen, enc, pTmpTree->pCur ); + + if(valueCount < VDATA_VALUE_COUNT_MAX) { + pTmpTree->pCur->pszValue[valueCount] = temp; + valueCount++; + } + else + free(temp); + } + + + pTmpTree->pCur->valueCount = valueCount; + pVCalRaw += dLen; + break; + } + // pVCalRaw += dLen; + // break; + } + + if (!done ) + { + DBG("@@@---- vcal_decode() lack VCLENDAR END and exit\n"); + vcal_free_vtree_memory(pVCal); + return NULL; + + } + + DBG( "------------------------------------------exit vcal_decode()--------------------------\n"); + + return pRes; +} + +/* + * vcal_free_vtree_memory() frees memory used for decoding. + * + * @param pTree VTree structure to be freed. + * @return If succeeds, return true, else false. + */ + bool +vcal_free_vtree_memory( VTree* pTree ) +{ + + VObject* pCurObj = NULL; + VObject* pNextObj = NULL; + VTree* pCurTree = NULL; + VTree* pNextTree = NULL; + + DBG( "vcal_free_vtree_memory() entered.\n"); + //SysRequireEx( pTree != NULL, false ); + retvm_if(NULL == pTree,NULL , "[ERROR]vcal_free_vtree_memory:Invalid parameter(pTree)!\n"); + + if ((pTree->treeType == VCALENDAR) || + ((pTree->treeType >= VEVENT) && + (pTree->treeType <= DAYLIGHT))) + { + //continue + ; + } + else + { + return false; + } + + + pCurTree = pTree; + + while ( pCurTree ) + { + pNextTree = pCurTree->pNext; + pCurObj = pCurTree->pTop; + + while ( pCurObj ) + { + int count; + int i; + + pNextObj = pCurObj->pSibling; + + count = pCurObj->valueCount; + + for ( i = 0; i < count; i++ ) + { + if ( pCurObj->pszValue[i] ) + { + free( pCurObj->pszValue[i] ); + pCurObj->pszValue[i] = NULL; + } + } + +#ifdef VDATA_GROUPNAME_SUPPORTED + if ( pCurObj->pszGroupName ) + { + free( pCurObj->pszGroupName ); + pCurObj->pszGroupName = NULL; + } +#endif // VDATA_GROUPNAME_SUPPORTED + + if ( pCurObj->pParam ) + { + VParam* pCurParam = NULL; + VParam* pNextParam = NULL; + + pCurParam = pCurObj->pParam; + + while ( pCurParam ) + { + pNextParam = pCurParam->pNext; + + free( pCurParam ); + pCurParam = NULL; + + pCurParam = pNextParam; + } + } + + free( pCurObj ); + pCurObj = NULL; + + pCurObj = pNextObj; + } + + free( pCurTree ); + pCurTree = NULL; + + pCurTree = pNextTree; + } + + DBG( "\n---------------------------exit vcal_free_vtree_memory--------- -------------\n"); + + return true; +} + + +/* + * vCaLTypeEncoder() compares the string and VCal type, parameter value. + * + * @param typeObj Data which will be encoded + * @param type Name of the type + * @return char * Encoded result + */ +static char* __VCalTypeEncode( VObject* pTypeObj, const char *pType ) +{ + int len; + char* pTemp = NULL; + char* szTypeValue = NULL; + int i; + int enc = 0; + char* pEncode = NULL; + char* pRes = NULL; + int total = 0; + int biLen = 0; + char* tempszTypeValue = NULL; + + DBG( "__VCalTypeEncode() enter..\n"); + + len = strlen( pType ); + biLen = pTypeObj->numOfBiData; + + if ( ( szTypeValue = ( char * )malloc( total += ( len+1+10 ) ) ) == NULL ) { + DBG( "VCalTypeEncode():malloc failed\n"); + return NULL; + } + + memset( szTypeValue, '\0', ( len+1+10 ) ); + memcpy( szTypeValue, pType, len ); + + pTemp = __VCalParamEncode( pTypeObj, &enc ); + if ( pTemp != NULL ) + { + len = strlen( pTemp ); + tempszTypeValue = szTypeValue; + if ( ( szTypeValue = ( char * )realloc( szTypeValue, ( total += len + 10 ) ) ) == NULL ){ + DBG( "__VCalTypeEncode():realloc failed\n"); + if (pTemp != NULL) { + free(pTemp); + pTemp = NULL; + } + + if(tempszTypeValue) { + free(tempszTypeValue); + tempszTypeValue = NULL; + } + return NULL; + } + strcat( szTypeValue, pTemp ); + free( pTemp ); + } + + tempszTypeValue = szTypeValue; + if ( ( szTypeValue = ( char * )realloc( szTypeValue, ( total += 2 + 10 ) ) ) == NULL ){ + + DBG( "__VCalTypeEncode():realloc failed\n"); + if(tempszTypeValue) { + free(tempszTypeValue); + tempszTypeValue = NULL; + } + return NULL; + } + strcat( szTypeValue, ":\0" ); + + len = 0; + for ( i = 0; i < pTypeObj->valueCount; i++ ){ + if( (pTypeObj->pszValue[i]==NULL)) { + free(szTypeValue); + return NULL; + } + + len += strlen( pTypeObj->pszValue[i] ); + } + + int buf_len = 0; + char *buf = NULL; + if ( !( pEncode = ( char * )calloc(1, (len+30)*2 + 31 )) ) { + free( szTypeValue ); + DBG( "__VCalTypeEncode():malloc failed\n"); + return NULL; + } + for ( i = 0; i < pTypeObj->valueCount; i++ ) { + int len_i = strlen(pTypeObj->pszValue[i]); + if( buf_len < len_i ) { + free(buf); + buf_len = len_i; + if( !(buf = (char*) calloc(1, buf_len*2 + 1 )) ) { + free( szTypeValue ); + DBG( "__VCalTypeEncode():malloc failed\n"); + free( pEncode ); + return NULL; + } + } else { + if(buf) + bzero(buf, buf_len); + } + + if(buf) + { + strncpy (buf, pTypeObj->pszValue[i], len_i); + _VEscape( buf ); + + if( i ) strcat( pEncode, ";"); + strcat( pEncode, buf ); + } + } + free( buf ); + + strcat( pEncode, "\0\0" ); + // _VEscape( pEncode ); + len = strlen( pEncode ); + + if ( enc & pCalEncValList[2].flag ) + { + + //if ( ( pRes = ( char * )malloc( len+40 ) ) == NULL ) + //if ( ( pRes = ( char * )malloc( len+40+10 ) ) == NULL ) + // Task description¿¡ enter°¡ µé¾î°¥ °æ¿ì memory ¸ðÀÚ¶÷. len * 4 + 30 -> len * 6 + 30À¸·Î º¯°æ 2004.3.12 + if ( ( pRes = ( char * )malloc( len*6+30 ) ) == NULL ) + { + DBG( "__VCalTypeEncode():malloc failed\n"); + + free( pEncode ); + free( szTypeValue ); + + return NULL; + } + _VQPEncode( pRes, pEncode ); + free( pEncode ); + pEncode = NULL; + } + else if ( enc & pCalEncValList[1].flag ) + { + + //if ( ( pRes = ( char * )malloc( ( len * 8 / 6 ) + 4 ) ) == NULL ) + if ( ( pRes = ( char * )malloc( ( len * 8 / 6 ) + 4 + 10 ) ) == NULL ) + { + DBG( "__VCalTypeEncode():malloc failed\n"); + free( pEncode ); + free( szTypeValue ); + + return NULL; + } + + //memset( pRes, '\0', ( ( len * 8 / 6 ) + 4 ) ); + memset( pRes, '\0', ( ( len * 8 / 6 ) + 4 + 10) ); + _gbase64Encode( pRes, pEncode, biLen ); + + free( pEncode ); + pEncode = NULL; + } + else + { + + //if ( ( pRes = ( char * )malloc( len+2 ) ) == NULL ) + if ( ( pRes = ( char * )malloc( len+2 + 10) ) == NULL ) + { + DBG( "__VCalTypeEncode():malloc failed\n"); + + free( pEncode ); + free( szTypeValue ); + + return NULL; + } + //memset( pRes, '\0', ( len + 2 ) ); + memset( pRes, '\0', ( len + 2 + 10 ) ); + memcpy( pRes, pEncode, len ); + free( pEncode ); + pEncode = NULL; + } + + strcat( pRes, "\r\n" ); //\n\0 -> \r\n ¼öÁ¤ ewpark 10.14th + + len = strlen( pRes ); + //if ( ( szTypeValue = ( char * )realloc( szTypeValue, ( total += ( len+3 ) ) ) ) == NULL ) + tempszTypeValue = szTypeValue; + if ( ( szTypeValue = ( char * )malloc( ( total += ( len*4 +3 + 10 ) ) ) ) == NULL ) + { + DBG( "__VCalTypeEncode():realloc failed\n"); + if (pEncode != NULL) + { + free( pEncode ); + pEncode = NULL; + } + if (pRes != NULL) + { + free( pRes ); + pRes = NULL; + } + if(tempszTypeValue) + { + free(tempszTypeValue); + tempszTypeValue = NULL; + } + + return NULL; + } + + memset(szTypeValue,0x00,total); + strncpy(szTypeValue,tempszTypeValue,total); + strcat( szTypeValue, pRes ); + _VRLSpace( szTypeValue ); + _VRTSpace( szTypeValue ); + + free(tempszTypeValue); + free( pRes ); + if ( strlen( szTypeValue ) >= 75 ) + { + if ( ( pEncode = ( char * )malloc( sizeof( char ) * ( strlen( szTypeValue )*4 + ( strlen( szTypeValue ) / 75 ) * 2 + 10 + 10 ) ) ) == NULL ) + { + DBG( "__VCalTypeEncode():malloc failed\n"); + free( szTypeValue ); + return NULL; + } + + _VFolding( pEncode, szTypeValue ); + free( szTypeValue ); + + return pEncode; + } + + DBG( "__VCalTypeEncode() end..\n"); + + return szTypeValue; +} + + +/* + * vcal_encode() compares the string and VCal type, parameter value. + * + * @param pVCalRaw Data which will be encoded + * @return char * Encoded result + */ + char* +vcal_encode( VTree* pVCalRaw ) +{ + char* pCalRes = NULL; + char* pTemp = NULL; + int len; + int total = 0; + VTree* pTmpTree = NULL; + VObject* pTmpObj = NULL; + + DBG( "vcal_encode() enter..\n"); + //SysRequireEx( pVCalRaw != NULL, NULL ); + if(pVCalRaw == NULL) + return NULL; + + if ((pVCalRaw->treeType == VCALENDAR) || + ((pVCalRaw->treeType >= VEVENT) && + (pVCalRaw->treeType <= DAYLIGHT))) + { + //continue + ; + } + else + { + return NULL; + } + + if ( ( pCalRes = ( char * )malloc( total += 2 ) ) == NULL ) + { + DBG( "vcal_encode():malloc failed\n"); + return NULL; + } + memset( pCalRes, '\0', 1); + + pTmpTree = pVCalRaw; + pTmpObj = pTmpTree->pTop; + + /* + if( (pTmpObj == NULL) || (pTmpObj->property < 0) || (pTmpObj->valueCount < 0) ) + { + if(pTmpObj !=NULL) + DBG( "pTmpObj = %d, pTmpObj->property = %d,pTmpObj->valueCount=%d \n",pTmpObj,pTmpObj->property,pTmpObj->valueCount); + else + DBG("pTmpObj is NULL"); + return NULL; + }*/ + + while ( true ) + { + switch ( pTmpTree->treeType ) + { + case VCALENDAR: + + // wyj add PRODID field,set PRODID length is 100 + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 18 + 100+15) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:VCALENDAR\r\n" ); + strcat( pCalRes, "PRODID:-//Tizen //Calendar //EN\r\n" ); + + strcat( pCalRes, "VERSION:1.0\r\n" ); + break; + case VEVENT: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 15 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:VEVENT\r\n" ); + break; + case VTODO: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 14 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:VTODO\r\n" ); + break; + case VJOURNAL: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 17 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:VJOURNAL\r\n" ); + break; + case VFREEBUSY: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 18 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:VFREEBUSY\r\n" ); + break; + case VTIMEZONE: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 19 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:VTIMEZONE\r\n" ); + break; + case VALARM: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 15 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:VALARM\r\n" ); + break; + case STANDARD: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 17 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:STANDARD\r\n" ); + break; + case DAYLIGHT: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 17 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "BEGIN:DAYLIGHT\r\n" ); + break; + } + + while ( true ) + { + if ( pTmpObj != NULL ) + { + if( pTmpObj->property <0 || pTmpObj->property >= VCAL_TYPE_NUM ) + { + if(pCalRes) + free(pCalRes); + return NULL; + } + if ( ( pTemp = __VCalTypeEncode( pTmpObj, pszCalTypeList[pTmpObj->property] ) ) != NULL ) + { + len = strlen( pTemp ); + if ( ( pCalRes = ( char *)realloc( pCalRes, ( total += ( len + 10 ) ) ) ) == NULL ) + { + DBG( "vcal_encode():realloc failed\n"); + free( pTemp ); + pTemp = NULL; + return NULL; + } + strcat( pCalRes, pTemp ); + free( pTemp ); + } + + if ( pTmpObj->pSibling != NULL ) + pTmpObj = pTmpObj->pSibling; + else + break; + } + else + break; + } + + switch ( pTmpTree->treeType ) + { + /* case VCALENDAR: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 15 ) ) ) == NULL ) + { + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + memcpy( pCalRes, "END:VCALENDAR\r\n", 17 ); + break; */ + case VEVENT: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 13 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:VEVENT\r\n" ); + break; + case VTODO: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 12 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:VTODO\r\n" ); + break; + case VJOURNAL: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 15 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:VJOURNALO\r\n" ); + break; + case VFREEBUSY: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 16 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:VFREEBUSY\r\n" ); + break; + case VTIMEZONE: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 16 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:VTIMEZONE\r\n" ); + break; + case VALARM: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 13 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:VALARM\r\n" ); + break; + case STANDARD: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 15 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:STANDARD\r\n" ); + break; + case DAYLIGHT: + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 15 ) ) ) == NULL ) + { + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:DAYLIGHT\r\n" ); + break; + } + + if ( pTmpTree->pNext != NULL ) + pTmpTree = pTmpTree->pNext; + else + break; + pTmpObj = pTmpTree->pTop; + } + + if ( ( pCalRes = ( char * )realloc( pCalRes, ( total += 16 ) ) ) == NULL ) + { + + DBG( "vcal_encode():realloc failed\n"); + return NULL; + } + strcat( pCalRes, "END:VCALENDAR\r\n" ); //\n\0 -> \r\n ¼öÁ¤ ewpark 10.14th + + DBG( "vcal_encode() end..\n"); + + return pCalRes; +} + + + +/* + * vCalParamEncoder() compares the string and VCal type, parameter value. + * + * @param typeObj Data which will be encoded + * @param type Name of the type + */ +static char* __VCalParamEncode( VObject* pTypeObj, int *pEnc ) +{ + char *szParam = NULL; + VParam *pTemp = NULL; + int i; + const ValueObj *pList; + bool bSupported; + int sNum; + int shift; + int len = 0; + + DBG( "__VCalParamEncode() enter..\n"); + retvm_if(NULL == pTypeObj,NULL , "[ERROR]__VCalParamEncode:Invalid parameter(pTypeObj)!\n"); + + pTemp = pTypeObj->pParam; + if ( pTemp != NULL ) + { + if ( ( szParam = ( char *)malloc( len += 2 ) ) == NULL ) + { + DBG( "__VCalParamEncode():malloc failed\n"); + return NULL; + } + memcpy( szParam, "\0\0", 2 ); + } + + while ( pTemp != NULL ) + { + bSupported = false; + + if ( ( szParam = ( char * )realloc( szParam, ( len += 15 ) ) ) == NULL ) + { + + DBG( "__VCalParamEncode():realloc failed\n"); + return NULL; + } + + strcat( szParam, ";" ); + strcat( szParam, pszCalParamList[pTemp->parameter] ); + strcat( szParam, "=" ); + + switch ( pTemp->parameter ) + { + case VCAL_PARAM_ENCODING: + *pEnc = pTemp->paramValue; + shift = VCAL_ENCODE_PARAM_NUM; + pList = pCalEncValList; bSupported = true; + break; + case VCAL_PARAM_CHARSET: + shift = VCAL_CHARSET_PARAM_NUM; + pList = pCalCharsetValList; bSupported = true; + break; + case VCAL_PARAM_TYPE: + shift = VCAL_TYPE_PARAM_NUM; + pList = pCalTypeValList; bSupported = true; + break; + case VCAL_PARAM_VALUE: + shift = VCAL_VALUE_PARAM_NUM; + pList = pCalValValList; bSupported = true; + break; + case VCAL_PARAM_EXPECT: + shift = VCAL_EXPECT_PARAM_NUM; + pList = pCalExpectValList; bSupported = true; + break; + case VCAL_PARAM_ROLE: + shift = VCAL_ROLE_PARAM_NUM; + pList = pCalRoleValList; bSupported = true; + break; + case VCAL_PARAM_RSVP: + shift = VCAL_RSVP_PARAM_NUM; + pList = pCalRSVPValList; bSupported = true; + break; + case VCAL_PARAM_STATUS: + shift = VCAL_STATUS_PARAM_NUM; + pList = pCalStatusValList; bSupported = true; + break; + case VCAL_PARAM_CUTYPE: + shift = VCAL_CUTYPE_PARAM_NUM; + pList = pCalCutypeValList; bSupported = true; + break; + case VCAL_PARAM_FBTYPE: + shift = VCAL_FBTYPE_PARAM_NUM; + pList = pCalFbtypeValList; bSupported = true; + break; + case VCAL_PARAM_PARTSTAT: + shift = VCAL_PARTSTAT_PARAM_NUM; + pList = pCalPartstatValList; bSupported = true; + break; + case VCAL_PARAM_RANGE: + shift = VCAL_RANGE_PARAM_NUM; + pList = pCalRangeValList; bSupported = true; + break; + case VCAL_PARAM_RELATED: + shift = VCAL_RELATED_PARAM_NUM; + pList = pCalRelatedValList; bSupported = true; + break; + case VCAL_PARAM_RELTYPE: + shift = VCAL_RELTYPE_PARAM_NUM; + pList = pCalReltypeValList; bSupported = true; + break; + default: + + if ( ( szParam = ( char *)realloc( szParam, 5 ) ) == NULL ) + { + DBG( "__VCalParamEncode():realloc failed\n"); + return NULL; + } + strcat( szParam, "NONE" ); + break; + } + + if ( bSupported == true ) + { + for ( i = 0, sNum = 0x00000001; i < shift; i++ ) + { + if ( pTemp->paramValue & sNum ) + { + if ( ( szParam = ( char * )realloc( szParam, + ( len += ( strlen( pList[i].szName ) + 2 ) ) ) ) == NULL ) + { + + DBG( "__VCalParamEncode():realloc failed\n"); + return NULL; + } + strcat( szParam, pList[i].szName ); + strcat( szParam, ", \0" ); + } + sNum <<= 1; + } + } + + for ( i = strlen( szParam ); i > 0 ; i-- ) + { + if ( szParam[i] == ' ' && szParam[i-1] == ',' ) + { + szParam[i-1] = '\0'; + break; + } + } + + if ( pTemp->pNext != NULL ) + pTemp = pTemp->pNext; + else + break; + } + + DBG( "\n ------end __VCalParamEncode ---------..\n"); + + return szParam; +} + +bool __cal_vcalendar_get_week_day_string(struct tm *start_time, char *s2) +{ + char *date_string[7] = { "SU","MO","TU","WE","TH","FR","SA" }; + + struct tm temp; + time_t t = timegm(start_time); + gmtime_r(&t, &temp); + + if(temp.tm_wday < 0 || temp.tm_wday > 6 ) + { + return false; + } + else + { + snprintf(s2, 3, date_string[temp.tm_wday]); + } + + return true; +} + +// in calendar schedule and todo data structure, the remind_tick is always 1 + bool +__cal_vcalendar_parse_reminder_time(const char * str, cal_sch_category_t category, struct tm * event_start_time, int * remind_tick, cal_sch_remind_tick_unit_t * remind_tick_unit) +{ + assert(str != NULL); + + struct tm tm={0,}; + struct tm base_tm={0,}; + + cal_vcalendar_convert_utc_str_to_tm(str, &tm); + base_tm.tm_year = event_start_time->tm_year; + base_tm.tm_mon = event_start_time->tm_mon; + base_tm.tm_mday = event_start_time->tm_mday; + if ((category == CAL_SCH_SPECIAL_OCCASION) || (category == CAL_SCH_BIRTHDAY)) + { + base_tm.tm_min = tm.tm_min; + base_tm.tm_hour = tm.tm_hour; + } + else + { + base_tm.tm_min = event_start_time->tm_min; + base_tm.tm_hour = event_start_time->tm_hour; + } + base_tm.tm_sec = 0; + tm.tm_sec = 0; + time_t gap_time = timegm(&base_tm) - timegm(&tm); + + *remind_tick = 1; + + if (gap_time < 0) + { + gap_time = 0 - gap_time; + *remind_tick_unit = CAL_SCH_TIME_UNIT_MIN; + *remind_tick = 0; + } + else if ((gap_time >= 0) && (gap_time < 60*60)) + { + *remind_tick_unit = CAL_SCH_TIME_UNIT_MIN; + *remind_tick = gap_time/60; + } + else if ((gap_time >= 60*60) && (gap_time < 60*60*24)) + { + *remind_tick_unit = CAL_SCH_TIME_UNIT_HOUR; + *remind_tick = gap_time/(60*60); + + } + else if ((gap_time >= 60*60*24) && (gap_time < 60*60*24*7)) + { + *remind_tick_unit = CAL_SCH_TIME_UNIT_DAY; + *remind_tick = gap_time/(60*60*24); + + } + else if ((gap_time >= 60*60*24*7) && (gap_time < 60*60*24*30)) + { + *remind_tick_unit = CAL_SCH_TIME_UNIT_WEEK; + *remind_tick = gap_time/(60*60*24*7); + + } + else if ((gap_time >= 60*60*24*30) && (gap_time < 60*60*24*365)) + { + *remind_tick_unit = CAL_SCH_TIME_UNIT_MONTH; + *remind_tick = gap_time/(60*60*24*30); + + } + + return true; +} + +// string format: D1 20020305T235959Z + bool +__cal_vcalendar_parse_sch_repeat_rule(const char *szText, cal_repeat_term_t * repeat_term, int * repeatInterval, struct tm * repeat_end_date,int *repeat_count) +{ + char szBuff[4]; + int startPos, strLen; + int i, j; + char c, c1, c2; + char *date_pos = NULL; + + startPos = 1; + j = 0; + + //check repeat term rule + if ( szText[0] == 'D' ) + { + *repeat_term = CAL_REPEAT_EVERY_DAY; + startPos = 1; + } + else if ( szText[0] == 'W' ) + { + *repeat_term = CAL_REPEAT_EVERY_WEEK; + startPos = 1; + } + else if ( szText[0] == 'M' ) + { + *repeat_term = CAL_REPEAT_EVERY_MONTH; + if ( szText[1] == 'P' ) + { + startPos = 2; + } + else if ( szText[1] == 'D' ) + { + startPos = 2; + } + } + else if ( szText[0] == 'Y' ) + { + *repeat_term = CAL_REPEAT_EVERY_YEAR; + if ( szText[1] == 'M' ) + { + startPos = 2; + } + else if ( szText[1] == 'D' ) + { + startPos = 2; + } + } + //check repeat interval + strLen = strlen(szText); + for ( i = startPos ; i < strLen ; i++ ) + { + if ( j < 4 ) + { + if (szText[i] != ' ') + { + szBuff[j] = szText[i]; + j++; + } + else + { + break; + } + } + else + { + return false; + } + + } + + szBuff[j] = '\0'; + *repeatInterval = atol(szBuff); + + startPos = i + 1; + + date_pos = strchr(szText + startPos, 'T'); + + if(date_pos == NULL) + { + date_pos = strchr(szText + startPos, '#'); + *repeat_count = atol(date_pos+1); + } + else + { + while(date_pos != NULL) { + c1 = *(date_pos - 1); + c2 = *(date_pos + 1); + + if(isdigit(c1) && isdigit(c2)) + { + do + { + c=*(--date_pos); + }while(c!=' '); + date_pos = date_pos + 1; // Skip ' '; + cal_vcalendar_convert_utc_str_to_tm(date_pos, repeat_end_date); + break; + } + if(date_pos + 1 == NULL) + { + break; + } + + date_pos = strchr(date_pos+1, 'T'); + } + } + + return true; +} + + bool +__cal_vcalendar_parse_sch_repeat_rule_for_ical(VObject* object , cal_repeat_term_t * repeat_term, int * repeatInterval, struct tm * repeat_end_date) +{ + int i = 0; + int j = 0; + int m = 0; + int value_count = 0; + char szBuff[4]; + int startPos = 0; + int strLen = 0; + + if (strcmp(object->pszValue[0], "FREQ=DAILY") == 0) + { + *repeat_term = CAL_REPEAT_EVERY_DAY; + } + else if (strcmp(object->pszValue[0], "FREQ=WEEKLY") == 0) + { + *repeat_term = CAL_REPEAT_EVERY_WEEK; + } + else if (strcmp(object->pszValue[0], "FREQ=MONTHLY") == 0) + { + *repeat_term = CAL_REPEAT_EVERY_MONTH; + } + else if (strcmp(object->pszValue[0], "FREQ=YEARLY") == 0) + { + *repeat_term = CAL_REPEAT_EVERY_YEAR; + } + else + { + *repeat_term = CAL_REPEAT_NONE; + } + + *repeatInterval = 1; + value_count = object->valueCount; + for (i = 1; i < value_count; i ++) + { + if (strstr(object->pszValue[i], "INTERVAL=") != NULL) + { + startPos = 9; + //check repeat interval + strLen = strlen(object->pszValue[i]); + for ( m = startPos ; m < strLen ; m++ ) + { + if ( j < 4 ) + { + if (object->pszValue[i][m] != ' ') + { + szBuff[j] = object->pszValue[i][m]; + j++; + } + else + { + break; + } + } + else + { + return false; + } + + } + szBuff[j] = '\0'; + *repeatInterval = atol(szBuff); + } + else if (strstr(object->pszValue[i], "UNTIL=") != NULL) + { + startPos = 6; + if (object->pszValue[i] + startPos != NULL) + { + cal_vcalendar_convert_utc_str_to_tm(object->pszValue[i] + startPos, repeat_end_date); + } + } + else + { + ; + } + } + + CALS_DBG( "\n-------------------__cal_vcalendar_parse_sch_repeat_rule_for_ical repeat item is %d, interval is %d --------------------\n",*repeat_term,*repeatInterval); + + return true; +} + + struct tm * +__cal_vcalendar_compute_pre_time(struct tm* start_tm, + struct tm *alarm_tm, const int remind_tick, const cal_sch_remind_tick_unit_t unit,struct tm *ret_tm) +{ + start_tm->tm_sec = 0; + alarm_tm->tm_sec = 0; + // time_t gap_time = cals_mktime(alarm_tm) - cals_mktime(start_tm); + time_t timep = timegm(alarm_tm); + time_t t = 0; + + // Fix for prevent - B. + switch (unit ) + { + case CAL_SCH_TIME_UNIT_MIN: + t = timep - 60*remind_tick; + break; + + case CAL_SCH_TIME_UNIT_HOUR: + t = timep - 60*60*remind_tick; + break; + + case CAL_SCH_TIME_UNIT_DAY: + t = timep - 24*60*60*remind_tick; + break; + case CAL_SCH_TIME_UNIT_WEEK: + t = timep - 7*24*60*60*remind_tick; + break; + + case CAL_SCH_TIME_UNIT_MONTH: + t = timep - 30*24*60*60*remind_tick; + break; + + default: + break; + + } + + return gmtime_r(&t,ret_tm); +} + + + bool +__cal_vcalendar_sch_vtree_add_object(VTree *tree, const cal_sch_full_t *sch, vCalType obj_type) +{ +#if 1 + + VObject* object; + int str_len = 0; + + assert((tree != NULL) && (sch != NULL)); + + object = (VObject*)malloc(sizeof(VObject)); + if ( !object ) + { + vcal_free_vtree_memory( tree ); + return false; + } + + memset( object, 0, sizeof(VObject)); + + switch(obj_type) + { + case VCAL_TYPE_CATEGORIES: + { + if(sch->cal_type == CAL_EVENT_TODO_TYPE) + { + break; + } + + object->property = VCAL_TYPE_CATEGORIES; + + object->pszValue[0] = (char*)malloc(20); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + memset(object->pszValue[0], 0, 20); + + switch (sch->sch_category) + { + case CAL_SCH_APPOINTMENT: + strcpy( object->pszValue[0], "APPOINTMENT"); + break; + + case CAL_SCH_HOLIDAY: + strcpy( object->pszValue[0], "HOLIDAY"); + break; + + case CAL_SCH_BUSSINESS: + strcpy( object->pszValue[0], "BUSINESS"); + break; + + case CAL_SCH_SPECIAL_OCCASION: + strcpy( object->pszValue[0], "SPECIAL OCCASION"); + break; + + case CAL_SCH_IMPORTANT: + strcpy( object->pszValue[0], "IMPORTANT"); + break; + + case CAL_SCH_BIRTHDAY: + strcpy( object->pszValue[0], "BIRTHDAY"); + break; + + default: + strcpy( object->pszValue[0], "MISCELLANEOUS"); + break; + + } + object->valueCount = 1; + } + break; + + case VCAL_TYPE_SUMMARY: + { + if (NULL != sch->summary && strlen(sch->summary) != 0) + { + object->property = VCAL_TYPE_SUMMARY; + str_len = strlen(sch->summary); + //str_len = (str_len>500)?500:str_len; + CALS_DBG("-------------------__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_SUMMARY(%d) -------------",str_len); + object->pParam = (VParam*)malloc(sizeof(VParam)); + if (!object->pParam) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + memset(object->pParam, 0, sizeof(VParam)); + + object->pParam->parameter = VCAL_PARAM_CHARSET; + object->pParam->paramValue = 0x01 << VCAL_CHARSET_PARAM_UTF_8; + object->pParam->pNext = NULL; + + object->pParam->pNext = (VParam*)malloc(sizeof(VParam)); + if (!object->pParam->pNext) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + memset(object->pParam->pNext, 0, sizeof(VParam)); + + object->pParam->pNext->parameter = VCAL_PARAM_ENCODING; + object->pParam->pNext->paramValue = 0x01<pszValue[0] = (char*)malloc(str_len*2 + 1 ); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + if (NULL != sch->summary) + { + memset(object->pszValue[0], 0, str_len + 1); + memcpy( object->pszValue[0], sch->summary, str_len); + } + CALS_DBG("sch->summary = %s,%s\n", sch->summary,object->pszValue[0]); + + object->valueCount = 1; + } + else + { + CAL_FREE(object); + + return true; + } + } + break; + + case VCAL_TYPE_DESCRIPTION: + { + CALS_DBG("---__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_DESCRIPTION/ -------------\n"); + + if (NULL != sch->description && strlen(sch->description) != 0) + { + object->property = VCAL_TYPE_DESCRIPTION; + str_len = strlen(sch->description); + //str_len = (str_len>500)?500:str_len; + + object->pParam = (VParam*)malloc(sizeof(VParam)); + if (!object->pParam) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + memset(object->pParam, 0, sizeof(VParam)); + + object->pParam->parameter = VCAL_PARAM_CHARSET; + object->pParam->paramValue = 0x01 << VCAL_CHARSET_PARAM_UTF_8; + object->pParam->pNext = NULL; + + object->pParam->pNext = (VParam*)malloc(sizeof(VParam)); + if (!object->pParam->pNext) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + memset(object->pParam->pNext, 0, sizeof(VParam)); + + object->pParam->pNext->parameter = VCAL_PARAM_ENCODING; + object->pParam->pNext->paramValue = 0x01<pszValue[0] = (char*)malloc(str_len + 1 ); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + if (sch->description) + { + memset(object->pszValue[0], 0, str_len + 1); + memcpy( object->pszValue[0], sch->description, str_len); + } + object->valueCount = 1; + + CALS_DBG("description = %s", object->pszValue[0]); + + } + else + { + CAL_FREE(object); + + return true; + } + + } + break; + case VCAL_TYPE_LOCATION: + { + CALS_DBG("-------------------__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_LOCATION -------------\n"); + + if (NULL != sch->location && strlen(sch->location) != 0) + { + object->property = VCAL_TYPE_LOCATION; + str_len = strlen(sch->location); + object->pParam = (VParam*)malloc(sizeof(VParam)); + if (!object->pParam) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + memset(object->pParam, 0, sizeof(VParam)); + + object->pParam->parameter = VCAL_PARAM_CHARSET; + object->pParam->paramValue = 0x01 << VCAL_CHARSET_PARAM_UTF_8; + object->pParam->pNext = NULL; + + object->pParam->pNext = (VParam*)malloc(sizeof(VParam)); + if (!object->pParam->pNext) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + memset(object->pParam->pNext, 0, sizeof(VParam)); + + object->pParam->pNext->parameter = VCAL_PARAM_ENCODING; + object->pParam->pNext->paramValue = 0x01; + + object->pszValue[0] = (char*)malloc(str_len + 1 ); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + if (sch->location) + { + memset(object->pszValue[0], 0, str_len + 1); + memcpy( object->pszValue[0], sch->location, str_len); + } + object->valueCount = 1; + } + else + { + CAL_FREE(object); + + return true; + } + + } + break; + case VCAL_TYPE_DTSTART: + { + CALS_DBG("-------------------__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_DTSTART -------------\n"); + + object->property = VCAL_TYPE_DTSTART; + + object->pszValue[0] = (char*)malloc(VCALENDAR_TIME_STR_LEN + 1); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + cal_vcalendar_convert_tm_to_vdata_str(&sch->start_date_time, object->pszValue[0]); + + object->valueCount = 1; + } + break; + + case VCAL_TYPE_DTEND: + { + CALS_DBG("-------------------__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_DTEND -------------\n"); + + if(sch->cal_type == CAL_EVENT_TODO_TYPE) + { + break; + } + + object->property = VCAL_TYPE_DTEND; + + object->pszValue[0] = (char*)malloc(VCALENDAR_TIME_STR_LEN + 1); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + cal_vcalendar_convert_tm_to_vdata_str(&sch->end_date_time, object->pszValue[0]); + + object->valueCount = 1; + } + break; + + // in Calendar sch data structure, there is no due data field + // end_date_time is assigned to due date + case VCAL_TYPE_DUE: + { + CALS_DBG( "-------------------__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_DUE -------------\n"); + + if(sch->cal_type != CAL_EVENT_TODO_TYPE) + { + break; + } + + object->property = VCAL_TYPE_DUE; + + object->pszValue[0] = (char*)malloc(VCALENDAR_TIME_STR_LEN + 1); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + cal_vcalendar_convert_tm_to_vdata_str(&sch->end_date_time, object->pszValue[0]); + + object->valueCount = 1; + } + break; + + case VCAL_TYPE_LAST_MODIFIED: + { + CALS_DBG( "-------------------__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_LAST_MODIFIED -------------\n"); + + object->property = obj_type; + object->pszValue[0] = (char*)malloc(VCALENDAR_TIME_STR_LEN + 1); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + // get current time + struct tm now; + + now.tm_year = 105; + now.tm_mon = 2; + now.tm_mday = 4; + now.tm_hour = 10; + now.tm_min = 12; + now.tm_sec = 34; + + cal_vcalendar_convert_tm_to_vdata_str(&now, object->pszValue[0]); + + object->valueCount = 1; + } + break; + + case VCAL_TYPE_AALARM: + { + CALS_DBG( "\n-------------------__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_AALARM -------------\n"); + + if (sch->alarm_list) + { + object->property = VCAL_TYPE_AALARM; + cal_alarm_info_t *tmp_alarm = ((cal_value *)sch->alarm_list->data)->user_data; + /* + // set alarm type + object->pParam = (VParam*)malloc(sizeof(VParam)); + if ( !object->pParam) + { + vcal_free_vtree_memory( tree ); + if (object != NULL) + { + CAL_FREE(object); + object = NULL; + } + return false; + } + memset(object->pParam, 0, sizeof(VParam)); + + object->pParam->parameter = VCAL_PARAM_TYPE; + + object->pParam->paramValue = 0x01 << VCAL_TYPE_PARAM_WAVE; + + // set alarm value + object->pParam->pNext = (VParam*)malloc(sizeof(VParam)); + if ( !object->pParam->pNext) + { + vcal_free_vtree_memory( tree ); + if (object != NULL) + { + CAL_FREE(object); + object = NULL; + } + return false; + } + + memset(object->pParam->pNext, 0, sizeof(VParam)); + + object->pParam->pNext->parameter = VCAL_PARAM_VALUE; + object->pParam->pNext->paramValue = 0x01 << VCAL_VALUE_PARAM_URL; + */ + + object->pszValue[0] = (char*)malloc(VCALENDAR_TIME_STR_LEN + 1); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + if (object != NULL) + { + free(object); + object = NULL; + } + return false; + } + struct tm ttm; + + // TODO: handle alarms(this is one alarm) + struct tm *tm = __cal_vcalendar_compute_pre_time((struct tm*)&sch->start_date_time, + &tmp_alarm->alarm_time, tmp_alarm->remind_tick, tmp_alarm->remind_tick_unit, &ttm); + cal_vcalendar_convert_tm_to_vdata_str(tm, object->pszValue[0]); + + // set audio reminder file + /* + object->pszValue[1] = (char*)malloc(FM_FILENAME_LEN_MAX + 1 ); + if (!(object->pszValue[1])) + { + vcal_free_vtree_memory( tree ); + if (object != NULL) + { + CAL_FREE(object); + object = NULL; + } + return false; + }*/ + + //memset(object->pszValue[1], 0, FM_FILENAME_LEN_MAX + 1); + //memcpy( object->pszValue[1], sch->alarm_tone, FM_FILENAME_LEN_MAX); + + object->valueCount = 1; + } + else + { + CAL_FREE(object); + + return true; + } + } + break; + + case VCAL_TYPE_RRULE: + { + CALS_DBG( "\n-------------------__cal_vcalendar_sch_vtree_add_object /VCAL_TYPE_RRULE -------------\n"); + + if (sch->repeat_term != CAL_REPEAT_NONE) + { + CALS_DBG(" ------------------------ begine to create RRULE-------------------------- "); + + object->property = VCAL_TYPE_RRULE; + + char repeat_end_date[VCALENDAR_TIME_STR_LEN + 1] = {0}; + char week_day_string[VCALENDAR_TIME_STR_LEN + 1] = {0}; + cal_vcalendar_convert_tm_to_vdata_str(&sch->repeat_end_date, repeat_end_date); + + CALS_DBG(" repeat_end_date = %s ", repeat_end_date); + + char str[100]; + memset(str, 0, 100); + + switch (sch->repeat_term) + { + case CAL_REPEAT_EVERY_DAY: + sprintf(str, "D%d %s", sch->repeat_interval, repeat_end_date); + break; + + case CAL_REPEAT_EVERY_WEEK: + case CAL_REPEAT_EVERY_WEEKDAYS: + __cal_vcalendar_get_week_day_string((struct tm*)&(sch->start_date_time), week_day_string); + sprintf(str, "W%d %s %s", sch->repeat_interval, week_day_string, repeat_end_date); + break; + + case CAL_REPEAT_EVERY_MONTH: + case CAL_REPEAT_EVERY_MONTH_DAY: + sprintf(str, "MD%d %s", sch->repeat_interval, repeat_end_date); + break; + + case CAL_REPEAT_EVERY_YEAR: + case CAL_REPEAT_EVERY_YEAR_DAY: + sprintf(str, "YM%d %s", sch->repeat_interval, repeat_end_date); + break; + + default: + break; + } + object->valueCount = 1; + + object->pszValue[0] = (char*)malloc(strlen(str) + 1); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory(tree); + CAL_FREE(object); + + return false; + } + memset(object->pszValue[0], 0, (strlen(str) + 1)); + strcpy(object->pszValue[0], str); + + CALS_DBG("RRULE = %s", object->pszValue[0]); + + } + else + { + CAL_FREE(object); + + return true; + } + } + break; + + case VCAL_TYPE_PRIORITY: + { + CALS_DBG( "\n-------------------__cal_vcalendar_todo_vtree_add_object /VCAL_TYPE_PRIORITY -------------\n"); + + object->property = VCAL_TYPE_PRIORITY; + + char str[3]; + memset(str, 0, 3); + + sprintf(str, "%d", sch->priority); + + object->pszValue[0] = (char*)malloc(3); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + memset(object->pszValue[0], 0, 3); + strcpy(object->pszValue[0], str); + + object->valueCount = 1; + } + break; + + case VCAL_TYPE_STATUS: + { + CALS_DBG( "\n-------------------__cal_vcalendar_todo_vtree_add_object /VCAL_TYPE_STATUS -------------\n"); + + if(sch->cal_type != CAL_EVENT_TODO_TYPE) + { + break; + } + + object->property = VCAL_TYPE_STATUS; + + object->pszValue[0] = (char*)malloc(20); + if ( !(object->pszValue[0]) ) + { + vcal_free_vtree_memory( tree ); + CAL_FREE(object); + + return false; + } + + memset(object->pszValue[0], 0, 20); + + switch (sch->task_status) + { + case CALS_EVENT_STATUS_TENTATIVE: + strcpy(object->pszValue[0], "TENTATIVE"); + break; + case CALS_EVENT_STATUS_CONFIRMED: + strcpy(object->pszValue[0], "CONFIRMED"); + break; + case CALS_EVENT_STATUS_CANCELLED: + strcpy(object->pszValue[0], "CANCELLED"); + break; + case CALS_TODO_STATUS_NEEDS_ACTION: + strcpy(object->pszValue[0], "NEEDS-ACTION"); + break; + case CALS_TODO_STATUS_COMPLETED: + strcpy(object->pszValue[0], "COMPLETED"); + break; + case CALS_TODO_STATUS_IN_PROCESS: + strcpy(object->pszValue[0], "IN-PROCESS"); + break; + case CALS_TODO_STATUS_CANCELLED: + strcpy(object->pszValue[0], "CANCELLED"); + break; + default: + strcpy(object->pszValue[0], "NEEDS-ACTION"); + break; + } + + object->valueCount = 1; + break; + } + + default: + break; + + } + + // if current is the header of the list + if (tree->pTop == NULL) + { + CALS_DBG( "\n--------tree->pTop = object--------------\n"); + tree->pTop = object; + } + else + { + tree->pCur->pSibling = object; + } + + // the object is the current object + tree->pCur = object; + +#endif + return true; +} + +#if 0 + bool +__cal_vnote_sch_vtree_add_object(VTree * tree, const cal_sch_full_t * sch, vCalType obj_type) +{ + VObject* object; + + assert((tree != NULL) && (sch != NULL)); + + object = (VObject*)malloc(sizeof(VObject)); + if ( !object ) + { + VNoteFreeVTreeMemory( tree ); + return false; + } + + memset( object, 0, sizeof(VObject)); + + switch(obj_type) + { + case VNOTE_TYPE_BODY: + { + INFO("---__cal_vnote_sch_vtree_add_object /VNOTE_TYPE_BODY -------------\n"); + +#if 1 + if (strlen(sch->description) != 0) + { + object->property = VNOTE_TYPE_BODY; + + object->pParam = (VParam*)malloc(sizeof(VParam)); + if ( !object->pParam) + { + VNoteFreeVTreeMemory( tree ); + if (object != NULL) + { + CAL_FREE(object); + object = NULL; + } + return false; + } + memset(object->pParam, 0, sizeof(VParam)); + memcpy( object->pszValue[0], sch->summary, CAL_SCH_SUMMARY_LEN_MAX); + + + // object->pParam->parameter = VNOTE_PARAM_ENCODING; + // object->pParam->paramValue = 0x01 << VNOTE_ENC_PARAM_QUOTED_PRINTABLE; + + // object->pszValue[0] = (char*)malloc(CAL_SCH_DESCRIPTION_LEN_MAX + 1 ); + if ( !(object->pszValue[0]) ) + { + VNoteFreeVTreeMemory( tree ); + CAL_FREE(object); + + return false; + } + + // memset(object->pszValue[0], 0, CAL_SCH_DESCRIPTION_LEN_MAX + 1); + memcpy( object->pszValue[0], sch->description, CAL_SCH_DESCRIPTION_LEN_MAX); + + object->valueCount = 1; + + } + else + { + CAL_FREE(object); + + return true; + } + +#else + + if (NULL != sch->description && strlen(sch->description) != 0) + { + object->property = VNOTE_TYPE_BODY; + + object->pszValue[0] = (char*)malloc(CAL_SCH_DESCRIPTION_LEN_MAX + 1 ); + if ( !(object->pszValue[0]) ) + { + VNoteFreeVTreeMemory( tree ); + if (object != NULL) + { + CAL_FREE(object); + object = NULL; + } + return false; + } + + if (sch->description) + { + memset(object->pszValue[0], 0, CAL_SCH_DESCRIPTION_LEN_MAX + 1); + memcpy( object->pszValue[0], sch->description, CAL_SCH_DESCRIPTION_LEN_MAX); + } + INFO("sch->description = %s\n", sch->description); + + object->valueCount = 1; + } + else + { + if (object != NULL) + { + CAL_FREE(object); + object = NULL; + } + return true; + } +#endif + + } + break; + + case VNOTE_TYPE_LAST_MODIFIED: + { + INFO("---__cal_vnote_sch_vtree_add_object /VNOTE_TYPE_LAST_MODIFIED -------------\n"); + + object->property = VNOTE_TYPE_LAST_MODIFIED; + object->pszValue[0] = (char*)malloc(VCALENDAR_TIME_STR_LEN + 1); + if ( !(object->pszValue[0]) ) + { + VNoteFreeVTreeMemory( tree ); + CAL_FREE(object); + + return false; + } + + // get current time + struct tm now; + + now.tm_year = 105; + now.tm_mon = 2; + now.tm_mday = 4; + now.tm_hour = 10; + now.tm_min = 12; + now.tm_sec = 34; + + cal_vcalendar_convert_tm_to_vdata_str(&now, object->pszValue[0]); + + object->valueCount = 1; + } + break; + + default: + break; + + } + + // if current is the header of the list + if (tree->pTop == NULL) + { + INFO( "\n--------tree->pTop = object--------------\n"); + tree->pTop = object; + } + else + { + tree->pCur->pSibling = object; + } + + // the object is the current object + tree->pCur = object; + + INFO( "\n-------------------exit __cal_vnote_sch_vtree_add_object --------------------\n"); + + return true; +} + +#endif + +bool _cal_convert_sch_to_vcalendar(const cal_sch_full_t *sch_array, + const int sch_count, char **vcal, cal_vCal_ver_t version) +{ +#if 1 + int i; + int j; + + VTree *cal_tree = NULL; + VTree *tmp_tree = NULL; + + vCalType obj_type[] = + { + VCAL_TYPE_SUMMARY, + VCAL_TYPE_DESCRIPTION, + VCAL_TYPE_LOCATION, + VCAL_TYPE_DTSTART, + VCAL_TYPE_DTEND, + VCAL_TYPE_LAST_MODIFIED, + VCAL_TYPE_ATTACH, + VCAL_TYPE_CATEGORIES, + VCAL_TYPE_PRIORITY, + VCAL_TYPE_STATUS, + VCAL_TYPE_AALARM, + VCAL_TYPE_RRULE, + 0 + }; + + + assert((sch_array != NULL) && (vcal != NULL)); + + + cal_tree = (VTree*)malloc(sizeof(VTree)); + if ( !cal_tree ) + return false; + + memset( cal_tree, 0, sizeof(VTree)); + + cal_tree->treeType = VCALENDAR; + cal_tree->pTop = NULL; + cal_tree->pCur = NULL; + cal_tree->pNext = NULL; + + VTree *tree = cal_tree; + + for ( i = 0; i < sch_count; i++) + { + tmp_tree = (VTree*)malloc(sizeof(VTree)); + if ( !tmp_tree ) + { + vcal_free_vtree_memory( cal_tree ); + return false; + } + + memset( tmp_tree, 0, sizeof(VTree)); + + if((sch_array + i)->cal_type == CAL_EVENT_TODO_TYPE){ + tmp_tree->treeType = VTODO; + obj_type[4]=VCAL_TYPE_DUE; + } + else + { + tmp_tree->treeType = VEVENT; + } + + tmp_tree->pTop = NULL; + tmp_tree->pCur = NULL; + tmp_tree->pNext = NULL; + + j=0; + while (obj_type[j]) + { + if ( !__cal_vcalendar_sch_vtree_add_object(tmp_tree, sch_array + i, obj_type[j]) ) + { + vcal_free_vtree_memory(cal_tree); + return false; + } + j++; + } + + tree->pNext = tmp_tree; + tree = tmp_tree; + + } + + tree->pNext = NULL; + + *vcal = vcal_encode( cal_tree ); + if ( *vcal == NULL ) + { + ERR("vcal_encode Failed"); + vcal_free_vtree_memory( cal_tree ); + return false; + } + + vcal_free_vtree_memory( cal_tree ); + CALS_DBG( "\n---------------------------exit _cal_convert_sch_to_vcalendar--------- -------------\n"); +#endif + return true; +} + + bool +_cal_convert_vcalendar_to_cal_data(const char *vcal, cal_sch_full_t **sch_array, int *sch_count) +{ + VTree* vCal = NULL; + VTree* tmp_tree = NULL; + VObject* object = NULL; + int error_code = 0; + bool start_date_exist = false; + char* pszAlarmValue = NULL; + bool is_ical = false; + + assert((vcal != NULL) && (sch_array != NULL)); + + /* decode VCalendar */ + vCal = vcal_decode ( (char*)vcal ); + if ( vCal == NULL ) + { + ERR( "vcal_decode() Failed"); + return false; + } + + tmp_tree = vCal; + int i = 0; + + *sch_array = malloc(sizeof(cal_sch_full_t)); + if(NULL == *sch_array) + { + ERR("malloc() Failed"); + return FALSE; + } + + error_code = cals_init_full_record(*sch_array); + + while(tmp_tree != NULL ) + { + + char buff[MAX_BUFFER_SIZE]; + if (i > 0) + { + *sch_array = realloc(*sch_array, sizeof(cal_sch_full_t) * (i + 1)); + if(NULL == *sch_array) + { + ERR("realloc() Failed"); + return false; + } + error_code = cals_init_full_record(*sch_array + i); + } + + memset(buff, 0, MAX_BUFFER_SIZE); + + if (tmp_tree->treeType == VTODO) + { + ((*sch_array) + i)->cal_type = CAL_EVENT_TODO_TYPE; + } + else if (tmp_tree->treeType == VEVENT) + { + ((*sch_array) + i)->cal_type = CAL_EVENT_SCHEDULE_TYPE; + } + /* + else if ((tmp_tree->treeType == STANDARD) || (tmp_tree->treeType == DAYLIGHT)) + { + object = tmp_tree->pTop; + while (true) + { + if (object->property == VCAL_TYPE_TZOFFSETFROM) + { + ((*sch_array) + i)->timezone = __cal_vcalendar_get_timezone(object->pszValue[0], (char**)timezoneoffset, 33); + } + + if ( object->pSibling != NULL ) + { + object = object->pSibling; + } + else + { + break; + } + } + tmp_tree = tmp_tree->pNext; + + continue; + }*/ + else if (tmp_tree->treeType == VCALENDAR) + { + object = tmp_tree->pTop; + while (true) + { + if (object->property == VCAL_TYPE_VERSION) + { + if (strcmp(object->pszValue[0], "2.0") == 0) + { + is_ical = true; + } + } + + if ( object->pSibling != NULL ) + { + object = object->pSibling; + } + else + { + break; + } + } + tmp_tree = tmp_tree->pNext; + + continue; + } + else + { + tmp_tree = tmp_tree->pNext; + continue; + } + + // initialize a sch + ((*sch_array) + i)->start_date_time.tm_year = 71; + ((*sch_array) + i)->start_date_time.tm_mon = 1; + ((*sch_array) + i)->start_date_time.tm_mday = 1; + ((*sch_array) + i)->start_date_time.tm_hour = 0; + ((*sch_array) + i)->start_date_time.tm_min = 0; + ((*sch_array) + i)->start_date_time.tm_sec = 0; + + ((*sch_array) + i)->end_date_time.tm_year = 71; + ((*sch_array) + i)->end_date_time.tm_mon = 1; + ((*sch_array) + i)->end_date_time.tm_mday = 1; + ((*sch_array) + i)->end_date_time.tm_hour = 0; + ((*sch_array) + i)->end_date_time.tm_min = 0; + ((*sch_array) + i)->end_date_time.tm_sec = 0; + + ((*sch_array) + i)->repeat_end_date.tm_year = 137; + ((*sch_array) + i)->repeat_end_date.tm_mon = 11; + ((*sch_array) + i)->repeat_end_date.tm_mday = 31; + ((*sch_array) + i)->repeat_end_date.tm_hour = 23; + ((*sch_array) + i)->repeat_end_date.tm_min = 59; + ((*sch_array) + i)->repeat_end_date.tm_sec = 59; + + (*sch_array + i)->sch_category = CAL_SCH_APPOINTMENT; + + object = tmp_tree->pTop; + + // read vcalendar and fill sch structure + while (true) + { + CALS_DBG(" \nproperty=%d \n",object->property); + + switch (object->property) + { + case VCAL_TYPE_CATEGORIES: + + //(*sch_array + i)->cal_type = CAL_EVENT_SCHEDULE_TYPE; + + CALS_DBG("sch_category = %s", object->pszValue[0]); + + if (strcmp(object->pszValue[0], "APPOINTMENT") == 0) + { + (*sch_array + i)->sch_category = CAL_SCH_APPOINTMENT; + + } + else if (strcmp(object->pszValue[0], "HOLIDAY") == 0) + { + (*sch_array + i)->sch_category = CAL_SCH_HOLIDAY; + + } + else if (strcmp(object->pszValue[0], "BUSINESS") == 0) + { + (*sch_array + i)->sch_category = CAL_SCH_BUSSINESS; + + } + else if (strcmp(object->pszValue[0], "SPECIAL OCCASION") == 0) + { + (*sch_array + i)->sch_category = CAL_SCH_SPECIAL_OCCASION; + + } + else if (strcmp(object->pszValue[0], "IMPORTANT") == 0) + { + (*sch_array + i)->sch_category = CAL_SCH_IMPORTANT; + + } + else if (strcmp(object->pszValue[0], "BIRTHDAY") == 0) + { + (*sch_array + i)->sch_category = CAL_SCH_BIRTHDAY; + + } + + else if (strcmp(object->pszValue[0], "MISCELLANEOUS") == 0) + { + (*sch_array + i)->sch_category = CAL_SCH_APPOINTMENT; + + } + else + { + (*sch_array + i)->sch_category = CAL_SCH_APPOINTMENT; + + } + + break; + + case VCAL_TYPE_SUMMARY: + (*sch_array + i)->summary = strdup(object->pszValue[0]); + // memcpy((*sch_array + i)->summary, object->pszValue[0], CAL_SCH_SUMMARY_LEN_MAX); + break; + case VCAL_TYPE_DESCRIPTION: + (*sch_array + i)->description = strdup(object->pszValue[0]); + //memcpy( (*sch_array + i)->description, object->pszValue[0], CAL_SCH_DESCRIPTION_LEN_MAX); + break; + case VCAL_TYPE_LOCATION: + (*sch_array + i)->location = strdup(object->pszValue[0]); + // memcpy( (*sch_array + i)->location, object->pszValue[0], CAL_SCH_LOCATION_LEN_MAX); + break; + + /* case VCAL_TYPE_ATTACH: + memcpy( (*sch_array + i)->attach_path, object->pszValue[0], FM_FILENAME_LEN_MAX); + break;*/ + + case VCAL_TYPE_DTSTART: + cal_vcalendar_convert_utc_str_to_tm(object->pszValue[0], &(*sch_array + i)->start_date_time); + start_date_exist = true; + break; + case VCAL_TYPE_DTEND: + cal_vcalendar_convert_utc_str_to_tm(object->pszValue[0], &(*sch_array + i)->end_date_time); + break; + case VCAL_TYPE_CREATED: + cal_vcalendar_convert_utc_str_to_tm(object->pszValue[0], &(*sch_array + i)->created_date_time); + break; + case VCAL_TYPE_COMPLETED: + cal_vcalendar_convert_utc_str_to_tm(object->pszValue[0], &(*sch_array + i)->completed_date_time); + break; + case VCAL_TYPE_DUE: + cal_vcalendar_convert_utc_str_to_tm(object->pszValue[0], &(*sch_array + i)->end_date_time); + break; + case VCAL_TYPE_LAST_MODIFIED: + cal_vcalendar_convert_utc_str_to_tm(object->pszValue[0], &(*sch_array + i)->last_modified_time); + + break; + case VCAL_TYPE_RRULE: + CALS_DBG( " \n---------------------VCAL_TYPE_RRULE is_ical is %d-------------------- \n",is_ical); + + // Calendar sch structure has no repeat interval field, discard it + struct tm tm; + tm.tm_year = 137; + tm.tm_mon = 11; + tm.tm_mday = 31; + tm.tm_hour = 23; + tm.tm_min = 59; + tm.tm_sec = 59; + int count = -1; + + if(is_ical) + { + __cal_vcalendar_parse_sch_repeat_rule_for_ical(object,&(*sch_array + i)->repeat_term, &(*sch_array + i)->repeat_interval, &tm); + } + else + { + __cal_vcalendar_parse_sch_repeat_rule( object->pszValue[0], &(*sch_array + i)->repeat_term, &(*sch_array + i)->repeat_interval, &tm,&count); + } + + if(count != -1) + { + (*sch_array + i)->repeat_occurrences = count; + } + + ((*sch_array + i)->repeat_end_date).tm_year = tm.tm_year; + ((*sch_array + i)->repeat_end_date).tm_mon = tm.tm_mon; + ((*sch_array + i)->repeat_end_date).tm_mday = tm.tm_mday; + ((*sch_array + i)->repeat_end_date).tm_hour = ((*sch_array + i)->end_date_time).tm_hour; + ((*sch_array + i)->repeat_end_date).tm_min = ((*sch_array + i)->end_date_time).tm_min; + ((*sch_array + i)->repeat_end_date).tm_sec = ((*sch_array + i)->end_date_time).tm_sec; + + if (((*sch_array + i)->repeat_term == CAL_REPEAT_EVERY_WEEK) || ((*sch_array + i)->repeat_term == CAL_REPEAT_EVERY_WEEKDAYS)) + { + (*sch_array + i)->week_flag = malloc(sizeof(char) * (DAY_OF_A_WEEK+1)); + memset((*sch_array + i)->week_flag,0x00,sizeof(char) * (DAY_OF_A_WEEK+1)); + cal_db_service_set_sch_weekflag(&((*sch_array + i)->start_date_time), (*sch_array + i)->week_flag); + } + CALS_DBG( " \n repeat_end_date->year = %d\n", ((*sch_array + i)->repeat_end_date).tm_year); + CALS_DBG( " \n repeat_end_date->mon = %d\n", ((*sch_array + i)->repeat_end_date).tm_mon); + CALS_DBG( " \n repeat_end_date->mday = %d\n", ((*sch_array + i)->repeat_end_date).tm_mday); + + break; + + // Note: Before decode AALARM, decode START_DATE_TIME first! + case VCAL_TYPE_AALARM: + CALS_DBG( " \n---------------------VCAL_TYPE_AALARM-------------------- \n"); + pszAlarmValue = object->pszValue[0]; + //__cal_vcalendar_parse_reminder_time(object->pszValue[0], &(*sch_array + i)->start_date_time, &(*sch_array + i)->remind_tick, &(*sch_array + i)->remind_tick_unit); + + /*if (object->pszValue[1] != NULL) + { + strncpy((*sch_array + i)->alarm_tone, object->pszValue[1], FM_FILENAME_LEN_MAX); + }*/ + break; + + // sch data structure has no priority and status fields + case VCAL_TYPE_PRIORITY: + CALS_DBG( " \n---------------------VCAL_TYPE_PRIORITY-------------------- \n"); + if (object->pszValue[0] != NULL) + { + + int prio = atoi(object->pszValue[0]); + if ((prio < 3) && (prio >= 0)) + { + (*sch_array + i)->priority = prio; + } + else + { + // INFO( " \n---------------------VCAL_TYPE_PRIORITY-HHHHHHHHH------------------- \n"); + + (*sch_array + i)->priority = CAL_PRIORITY_HIGH; + } + + } + + break; + + case VCAL_TYPE_STATUS: + CALS_DBG( " \n---------------------VCAL_TYPE_STATUS-------------------- \n"); + + if ( object->pszValue[0] != NULL) + { + if (CAL_EVENT_TODO_TYPE == (*sch_array + i)->cal_type) { + if (strcmp(object->pszValue[0], "NEEDS-ACTION") == 0) + (*sch_array + i)->task_status = CALS_TODO_STATUS_NEEDS_ACTION; + else if (strcmp(object->pszValue[0], "COMPLETED") == 0) + (*sch_array + i)->task_status = CALS_TODO_STATUS_COMPLETED; + else if (strcmp(object->pszValue[0], "IN-PROCESS") == 0) + (*sch_array + i)->task_status = CALS_TODO_STATUS_IN_PROCESS; + else if (strcmp(object->pszValue[0], "CANCELLED") == 0) + (*sch_array + i)->task_status = CALS_TODO_STATUS_CANCELLED; + else + (*sch_array + i)->task_status = CALS_STATUS_NONE; + } else if (CAL_EVENT_SCHEDULE_TYPE == (*sch_array + i)->cal_type) { + if (strcmp(object->pszValue[0], "TENTATIVE") == 0) + (*sch_array + i)->task_status = CALS_EVENT_STATUS_TENTATIVE; + else if (strcmp(object->pszValue[0], "CONFIRMED") == 0) + (*sch_array + i)->task_status = CALS_EVENT_STATUS_CONFIRMED; + else if (strcmp(object->pszValue[0], "CANCELLED") == 0) + (*sch_array + i)->task_status = CALS_EVENT_STATUS_CANCELLED; + else + (*sch_array + i)->task_status = CALS_STATUS_NONE; + } + } + break; + + default: + break; + + } + + if ( object->pSibling != NULL ) + { + object = object->pSibling; + } + else + { + break; + } + } /* while */ + + if(false == start_date_exist) + { + memcpy(&(*sch_array + i)->start_date_time,&(*sch_array + i)->start_date_time,sizeof(struct tm)); + } + + + if(((*sch_array + i)->start_date_time.tm_hour==0) && ((*sch_array + i)->start_date_time.tm_min==0) && + ((*sch_array + i)->start_date_time.tm_sec==0) && ((*sch_array + i)->end_date_time.tm_hour==0) && + ((*sch_array + i)->end_date_time.tm_min==0) && ((*sch_array + i)->end_date_time.tm_sec==0)) + { + (*sch_array + i)->all_day_event = true; + } + + if(pszAlarmValue && pszAlarmValue[0] != '\0') + { + cal_alarm_info_t *alarm; + cal_value *val; + + val = calendar_svc_value_new(CAL_VALUE_LST_ALARM); // Alarm value create + + alarm = (cal_alarm_info_t *)val->user_data; + __cal_vcalendar_parse_reminder_time(pszAlarmValue, (*sch_array + i)->sch_category, + &(*sch_array + i)->start_date_time, &alarm->remind_tick, &alarm->remind_tick_unit); + cal_vcalendar_convert_utc_str_to_tm(pszAlarmValue, &alarm->alarm_time); + + if (((*sch_array + i)->sch_category == CAL_SCH_SPECIAL_OCCASION) || + ((*sch_array + i)->sch_category == CAL_SCH_BIRTHDAY)) { + alarm->alarm_time.tm_year = (*sch_array + i)->start_date_time.tm_year; + alarm->alarm_time.tm_mon = (*sch_array + i)->start_date_time.tm_mon; + alarm->alarm_time.tm_mday = (*sch_array + i)->start_date_time.tm_mday; + } else { + cal_db_service_copy_struct_tm(&((*sch_array + i)->start_date_time), &alarm->alarm_time); + } + + (*sch_array + i)->alarm_list = g_list_append((*sch_array + i)->alarm_list, val); + + CALS_DBG( "remind_tick = %d", alarm->remind_tick); + CALS_DBG( "remind_tick_unit = %d", alarm->remind_tick_unit); + pszAlarmValue = NULL; + } + + /* int len = strlen((*sch_array + i)->description); + + strncat((*sch_array + i)->description, buff, CAL_SCH_DESCRIPTION_LEN_MAX - len -10);*/ + + tmp_tree = tmp_tree->pNext; + + i++; + } + + *sch_count = i; + + /* Free VCalendar Tree */ + vcal_free_vtree_memory( vCal ); + return true; +} diff --git a/src/cals-ical-codec.h b/src/cals-ical-codec.h new file mode 100755 index 0000000..3976f7f --- /dev/null +++ b/src/cals-ical-codec.h @@ -0,0 +1,474 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_ICAL_CODEC_H__ +#define __CALENDAR_SVC_ICAL_CODEC_H__ + +#define CR 0x0d +#define LF 0x0a +#define TAB 0x09 +#define WSP 0x20 +#define UNKNOWN_NAME 0x80000000 + +#define VCALENDAR 0x02 +#define VNOTE 0x0b + +#define VEVENT 0x03 +#define VTODO 0x04 +#define VJOURNAL 0x05 +#define VFREEBUSY 0x06 +#define VTIMEZONE 0x07 +#define VALARM 0x08 +#define VMESSAGE 0x0c +#define VBODY 0X0d +#define STANDARD 0x09 +#define DAYLIGHT 0x0a + +#define VTYPE_TOKEN_SEMICOLON ';' +#define VTYPE_TOKEN_COLON ':' +#define VTYPE_TOKEN_EQUAL '=' +#define VTYPE_TOKEN_COMMA ',' +#define VTYPE_TOKEN_DOT '.' +#define VTYPE_TOKEN_QUOTE '\'' +#define VTYPE_TOKEN_DBLQUOTE '"' + +#define VDATA_VALUE_COUNT_MAX 2000 + +/****************************************************************************************************/ +/* ENUMERATION DECLARATION */ +/****************************************************************************************************/ +/* Property */ +typedef enum +{ + VCAL_TYPE_AALARM, + VCAL_TYPE_ACTION, + VCAL_TYPE_ATTACH, + VCAL_TYPE_ATTENDEE, + VCAL_TYPE_BEGIN, + VCAL_TYPE_CALSCALE, + VCAL_TYPE_CATEGORIES, + VCAL_TYPE_CLASS, + VCAL_TYPE_COMMENT, + VCAL_TYPE_COMPLETED, + VCAL_TYPE_CONTACT, + VCAL_TYPE_CREATED, + VCAL_TYPE_DALARM, + VCAL_TYPE_DAYLIGHT, + VCAL_TYPE_DCREATED, + VCAL_TYPE_DESCRIPTION, + VCAL_TYPE_DTEND, + VCAL_TYPE_DTSTAMP, + VCAL_TYPE_DTSTART, + VCAL_TYPE_DUE, + VCAL_TYPE_DURATION, + VCAL_TYPE_END, + VCAL_TYPE_EXDATE, + VCAL_TYPE_EXRULE, + VCAL_TYPE_FREEBUSY, + VCAL_TYPE_GEO, + VCAL_TYPE_LAST_MODIFIED, + VCAL_TYPE_LOCATION, + VCAL_TYPE_MALARM, + VCAL_TYPE_METHOD, + VCAL_TYPE_ORGANIZER, + VCAL_TYPE_PALARM, + VCAL_TYPE_PERCENT_COMPLETE, + VCAL_TYPE_PRIORITY, + VCAL_TYPE_PRODID, + VCAL_TYPE_RDATE, + VCAL_TYPE_RECURRENCE_ID, + VCAL_TYPE_RELATED_TO, + VCAL_TYPE_REPEAT, + VCAL_TYPE_REQUEST_STATUS, + VCAL_TYPE_RESOURCES, + VCAL_TYPE_RNUM, + VCAL_TYPE_RRULE, + VCAL_TYPE_SEQUENCE, + VCAL_TYPE_STANDARD, + VCAL_TYPE_STATUS, + VCAL_TYPE_SUMMARY, + VCAL_TYPE_TRANSP, + VCAL_TYPE_TRIGGER, + VCAL_TYPE_TZ, + VCAL_TYPE_TZID, + VCAL_TYPE_TZNAME, + VCAL_TYPE_TZOFFSETFROM, + VCAL_TYPE_TZOFFSETTO, + VCAL_TYPE_TZURL, + VCAL_TYPE_URL, + VCAL_TYPE_UID, + VCAL_TYPE_VALARM, + VCAL_TYPE_VCALENDAR, + VCAL_TYPE_VERSION, + VCAL_TYPE_VEVENT, + VCAL_TYPE_VFREEBUSY, + VCAL_TYPE_VJOURNAL, + VCAL_TYPE_VTIMEZONE, + VCAL_TYPE_VTODO, + VCAL_TYPE_ALLDAY +}vCalType; + +#define VCAL_TYPE_NUM 66 + +/* Parameter */ +typedef enum +{ + VCAL_PARAM_ALTREP, + VCAL_PARAM_CHARSET, + VCAL_PARAM_CN, + VCAL_PARAM_CONTEXT, + VCAL_PARAM_CUTYPE, + VCAL_PARAM_DELEGATED_FROM, + VCAL_PARAM_DELEGATED_TO, + VCAL_PARAM_DIR, + VCAL_PARAM_ENCODING, + VCAL_PARAM_EXPECT, + VCAL_PARAM_FBTYPE, + VCAL_PARAM_FMTYPE, + VCAL_PARAM_LANGUAGE, + VCAL_PARAM_MEMBER, + VCAL_PARAM_PARTSTAT, + VCAL_PARAM_RANGE, + VCAL_PARAM_RELATED, + VCAL_PARAM_RELTYPE, + VCAL_PARAM_ROLE, + VCAL_PARAM_RSVP, + VCAL_PARAM_SENT_BY, + VCAL_PARAM_STATUS, + VCAL_PARAM_TYPE, + VCAL_PARAM_TZID, + VCAL_PARAM_VALUE +}vCalendarParamName; + +#define VCAL_PARAM_NUM 25 + +/* Cu type value */ +typedef enum +{ + VCAL_CUTYPE_PARAM_GROUP, + VCAL_CUTYPE_PARAM_INDIVIDUAL, + VCAL_CUTYPE_PARAM_RESOURCE, + VCAL_CUTYPE_PARAM_ROOM, + VCAL_CUTYPE_PARAM_UNKNOWN +} vCalCutypeVal; + +#define VCAL_CUTYPE_PARAM_NUM 5 + +/* Parameter encoding value */ +typedef enum +{ + VCAL_ENC_PARAM_B, + VCAL_ENC_PARAM_BASE64, + VCAL_ENC_PARAM_QUOTED_PRINTABLE, + VCAL_ENC_PARAM_7BIT, + VCAL_ENC_PARAM_8BIT +}vCalEncVal; + +#define VCAL_ENCODE_PARAM_NUM 5 + +/* Fb Type value */ +typedef enum +{ + VCAL_FBTYPE_PARAM_BUSY, + VCAL_FBTYPE_PARAM_BUSY_TENTATIVE, + VCAL_FBTYPE_PARAM_BUSY_UNAVAILABLE, + VCAL_FBTYPE_PARAM_FREE +} vCalFbtypeVal; + +#define VCAL_FBTYPE_PARAM_NUM 4 + +/* Partstat value */ +typedef enum +{ + VCAL_PARTSTAT_PARAM_ACCEPTED, + VCAL_PARTSTAT_PARAM_COMPLETED, + VCAL_PARTSTAT_PARAM_DELEGATED, + VCAL_PARTSTAT_PARAM_DECLINED, + VCAL_PARTSTAT_PARAM_IN_PROCESS, + VCAL_PARTSTAT_PARAM_NEED_ACTION, + VCAL_PARTSTAT_PARAM_TENTATIVE +} vCalPartstatVal; + +#define VCAL_PARTSTAT_PARAM_NUM 7 + +/* Range value */ +typedef enum +{ + VCAL_RANGE_PARAM_THISANDFUTURE, + VCAL_RANGE_PARAM_THISANDPRIOR +} vCalRangeVal; + +#define VCAL_RANGE_PARAM_NUM 2 + +/* Related value */ +typedef enum +{ + VCAL_RELATED_PARAM_END, + VCAL_RELATED_PARAM_START +} vCalRelatedVal; + +#define VCAL_RELATED_PARAM_NUM 2 + +/* Rel type value */ +typedef enum +{ + VCAL_RELTYPE_PARAM_CHILD, + VCAL_RELTYPE_PARAM_PARENT, + VCAL_RELTYPE_PARAM_SIBLING +} vCalReltypeVal; + +#define VCAL_RELTYPE_PARAM_NUM 3 + +/* Value value */ +typedef enum +{ + VCAL_VALUE_PARAM_BINARY, + VCAL_VALUE_PARAM_BOOLEAN, + VCAL_VALUE_PARAM_CAL_ADDRESS, + VCAL_VALUE_PARAM_CID, + VCAL_VALUE_PARAM_CONTENT_ID, + VCAL_VALUE_PARAM_DATE, + VCAL_VALUE_PARAM_DATE_TIME, + VCAL_VALUE_PARAM_DURATION, + VCAL_VALUE_PARAM_FLOAT, + VCAL_VALUE_PARAM_INTEGER, + VCAL_VALUE_PARAM_PERIOD, + VCAL_VALUE_PARAM_PHONE_NUMBER, + VCAL_VALUE_PARAM_RECUR, + VCAL_VALUE_PARAM_TEXT, + VCAL_VALUE_PARAM_TIME, + VCAL_VALUE_PARAM_URI, + VCAL_VALUE_PARAM_URL, + VCAL_VALUE_PARAM_UTC_OFFSET, + VCAL_VALUE_PARAM_VCALENDAR, + VCAL_VALUE_PARAM_VEVENT, + VCAL_VALUE_PARAM_VTODO +}vCalValVal; + +#define VCAL_VALUE_PARAM_NUM 21 + +/* Parameter type value */ +typedef enum +{ + VCAL_TYPE_PARAM_AIFF, + VCAL_TYPE_PARAM_BBS, + VCAL_TYPE_PARAM_CAR, + VCAL_TYPE_PARAM_CELL, + VCAL_TYPE_PARAM_DOM, + VCAL_TYPE_PARAM_FAX, + VCAL_TYPE_PARAM_GIF, + VCAL_TYPE_PARAM_HOME, + VCAL_TYPE_PARAM_INTL, + VCAL_TYPE_PARAM_INTERNET, + VCAL_TYPE_PARAM_ISDN, + VCAL_TYPE_PARAM_JPEG, + VCAL_TYPE_PARAM_MODEM, + VCAL_TYPE_PARAM_MSG, + VCAL_TYPE_PARAM_PAGER, + VCAL_TYPE_PARAM_PARCEL, + VCAL_TYPE_PARAM_PCM, + VCAL_TYPE_PARAM_PCS, + VCAL_TYPE_PARAM_PNG, + VCAL_TYPE_PARAM_POSTAL, + VCAL_TYPE_PARAM_PREF, + VCAL_TYPE_PARAM_VCARD, + VCAL_TYPE_PARAM_VIDEO, + VCAL_TYPE_PARAM_VOICE, + VCAL_TYPE_PARAM_WAVE, + VCAL_TYPE_PARAM_WBMP, + VCAL_TYPE_PARAM_WORK, + VCAL_TYPE_PARAM_X400 +}vCalTypeVal; + +#define VCAL_TYPE_PARAM_NUM 28 + +/* Parameter expect value */ +typedef enum +{ + VCAL_EXPECT_PARAM_FYI, + VCAL_EXPECT_PARAM_IMMEDIATE, + VCAL_EXPECT_PARAM_REQUEST, + VCAL_EXPECT_PARAM_REQUIRE +}vCalExpectVal; + +#define VCAL_EXPECT_PARAM_NUM 4 + +/* Parameter role value */ +typedef enum +{ + VCAL_ROLE_PARAM_ATTENDEE, + VCAL_ROLE_PARAM_CHAIR, + VCAL_ROLE_PARAM_DELEGATE, + VCAL_ROLE_PARAM_NON_PARTICIPANT, + VCAL_ROLE_PARAM_OPT_PARTICIPANT, + VCAL_ROLE_PARAM_ORGANIZER, + VCAL_ROLE_PARAM_OWNER, + VCAL_ROLE_PARAM_REQ_PARTICIPANT +}vCalRoleVal; + +#define VCAL_ROLE_PARAM_NUM 8 + +/* Parameter RSVP value */ +typedef enum +{ + VCAL_RSVP_PARAM_FALSE, + VCAL_RSVP_PARAM_NO, + VCAL_RSVP_PARAM_TRUE, + VCAL_RSVP_PARAM_YES +}vCalRsvpVal; + +#define VCAL_RSVP_PARAM_NUM 4 + +/* Parameter Charset value */ +typedef enum +{ + VCAL_CHARSET_PARAM_UTF_8, + VCAL_CHARSET_PARAM_UTF_16, + VCAL_CHARSET_PARAM_SHIFT_JIS +}vCalCharsetVal; + +#define VCAL_CHARSET_PARAM_NUM 2 + +/* Parameter STATUS value */ +typedef enum +{ + VCAL_STATUS_PARAM_ACCEPTED, + VCAL_STATUS_PARAM_COMPLETED, + VCAL_STATUS_PARAM_CONFIRMED, + VCAL_STATUS_PARAM_DECLINED, + VCAL_STATUS_PARAM_DELEGATED, + VCAL_STATUS_PARAM_NEEDS_ACTION, + VCAL_STATUS_PARAM_SENT, + VCAL_STATUS_PARAM_TENTATIVE +}vCalStatusVal; + +#define VCAL_STATUS_PARAM_NUM 8 + + +/* VCalendar encoder/decoder status */ +#define VCAL_TYPE_NAME_STATUS 1 +#define VCAL_PARAM_NAME_STATUS 2 +#define VCAL_TYPE_VALUE_STATUS 3 +#define VCAL_PARAM_VALUE_STATUS 4 + + +/****************************************************************************************************/ +/* GLOBAL STRUCTURE DECLARATION */ +/****************************************************************************************************/ + +typedef struct _VParam VParam; +typedef struct _VObject VObject; +typedef struct _ValueObj ValueObj; +typedef struct _VTree VTree; + +struct _VTree +{ + int treeType; + VObject* pTop; + VObject* pCur; + VTree* pNext; +}; + +struct _VParam +{ + int parameter; + int paramValue; + VParam* pNext; +}; + +struct _VObject +{ + int property; + VParam* pParam; + int valueCount; + int numOfBiData; + char* pszValue[VDATA_VALUE_COUNT_MAX]; + VObject* pSibling; + VObject* pParent; + VObject* pChild; + + char* pszGroupName; //VDATA_GROUPNAME_SUPPORTED +}; + +struct _ValueObj +{ + char* szName; + int flag; +}; + + +#define FEATURE_SHIFT_JIS + +/****************************************************************************************************/ +/* FUNCTION DECLARATION */ +/****************************************************************************************************/ +int _VIsSpace( char ); +int _VRLSpace( char * ); +int _VRTSpace( char * ); +int _VUnescape( char *); +int _VEscape(char*); +int _VManySpace2Space( char * ); +int _VB64Decode( char *, char * ); +int _VB64Encode( char *, char *, int ); +int _VUnfolding( char * ); +void _VFolding( char *, char * ); +int _VQPDecode( char * ); +int _VQPEncode( char *, char * ); + +void _VFoldingQP( char *result, char *contentline ); +void _VFoldingNoSpace( char *result, char *contentline ); +int _VManyCRLF2CRLF(char *pIn); +int _VUnfoldingNoSpec( char *string, int vType ); + + +/** +* @fn VTree* vcal_decode(char* pVCalRaw); +* This function decodes a vCalendar raw buffer +* @return This function returns a pointer to VTree. +* @param[in] pVCalRaw Points to the vCalendar raw buffers. +* @see vcal_encode +*/ + +VTree* vcal_decode(char *pVCalRaw); + +/** +* @fn char* vcal_encode(VTree* pVTree); +* This function encodes a vTree data to vCalendar buffer +* @return This function returns a pointer to vCalendar buffer. +* @param[in] pVTree Points to vTree data. +* @see vcal_decode +*/ + +char *vcal_encode(VTree* pVTree); + +/** +* @fn bool vcal_free_vtree_memory( VTree* pTree ); +* This function free vTree memory +* @return This function returns true if success and false if failuer. +* @param[in] pTree Points to a vTree data. +* @see vcal_decode +*/ + +bool vcal_free_vtree_memory( VTree* pTree ); + +bool _cal_convert_sch_to_vcalendar(const cal_sch_full_t *sch_array, const int sch_count, char** vcal, cal_vCal_ver_t version ); + +bool _cal_convert_vcalendar_to_cal_data(const char *vcal, cal_sch_full_t **sch_array, int *sch_count); + + +#endif /* __CALENDAR_SVC_ICAL_CODEC_H__ */ diff --git a/src/cals-ical-utils.c b/src/cals-ical-utils.c new file mode 100755 index 0000000..49b8d76 --- /dev/null +++ b/src/cals-ical-utils.c @@ -0,0 +1,1151 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include + +#include "cals-typedef.h" +#include "cals-ical-codec.h" + +#define VCARD_TYPE_NUM 34 +#define VCAL_TYPE_NUM 66 +#define VMSG_TYPE_NUM 12 + +/* BASE64 TABLE */ +static const char Base64Table[65] = { 'A', + 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', + 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', + '9', '+', '/', '=' +}; + +/* Function Declaration */ +static int __VFindBase64( char ); +static int __VBase64Check( char * ); +static char __VHexaDecoder( char * ); +static void __VHexaEncoder( char * ); +static int __VIsPrintable( char ); + + +/** + * vCardIsSpace() returns one if char is either a space, tab, or newline. + * + * @param s1 [in] pointer to first string. + * @param s2 [in] pointer to second string. + * @return 1 'in' is a space character. + * @return 0 'in' is not a space. + */ + int +_VIsSpace( char in ) +{ + //DLOG( "_VIsSpace() enter..\n"); + + if ( ( in == TAB ) || ( in == WSP ) ) + { + return 1; + } + else + { + return 0; + } +} + + +/* + * vRemLeadSpace() removes leading space in string 'in'. + * + * @param in [inout] pointer to string. + * @return 0 if success. + */ + int +_VRLSpace( char *in ) +{ + int i, j; + short int done; + + //DLOG( "_VRLSpace() enter..\n"); + + i = 0; + done = 0; + + while ( !done && in[i] ) + { + if ( _VIsSpace( in[i] ) ) + { + i++; + } + else + { + done = 1; + } + } + + j = 0; + while ( in[i] ) + { + in[j++] = in[i++]; + } + + in[j] = '\0'; + + return 0; +} + + +/* + * vRemTermSpace() removes terminating space. + * + * @param in [inout] pointer to string. + * @return 0 if success. + */ + int +_VRTSpace( char *in ) +{ + int i; + short int done; + + //DLOG( "_VRTSpace() enter..\n"); + + i = strlen(in) - 1; + done = 0; + + while ( !done && !( i < 0 ) ) + { + if ( _VIsSpace( in[i] ) ) + { + in[i--] = '\0'; + } + else + { + done = 1; + } + } + + return(0); +} + + +/* + * VUnescape() unescapes escaped character. + * + * @param in [inout] pointer to string. + * @return 0 if success. + */ + int +_VUnescape( char *in ) +{ + int i; + int index; + int len; + char c1, c2; + + //DLOG( "_VUnescape() enter..\n"); + + len = strlen(in); + + for ( i = 0, index = 0; i < len; i++ ) + { + c1 = in[i]; + + if ( c1 == '\\' ) + { + c2 = in[i+1]; + if ( c2 == ';' ) continue; + } + in[index++] = c1; + } + + in[index] = '\0'; + + return(0); +} + +/* + * VEscape() escapes character. + * + * @param in [inout] pointer to string. + * @return 0 if success. + */ + int +_VEscape( char *in ) +{ + int i; + int index; + int len; + char *buf = NULL; + char c; + + //DLOG( "_VEscape() enter..\n"); + + len = strlen(in); + buf = (char*) calloc(1, len*2+1); + + for ( i = 0, index = 0; i < len; i++ ){ + c = in[i]; + if ( c == ';' ) { + buf[index++] = '\\'; + } + buf[index++] = c; + } + + strncpy( in, buf, len*2+1 ); + free(buf); + + return(0); +} + + + +/* + * vManySpace2Space() converts multiple spaces to single space in 'in'. + * + * @param in [inout] pointer to string. + * @return int length of converted string. + */ + int +_VManySpace2Space( char *in ) +{ + int i, j; + int spaced = 0; + + //DLOG( "_VManySpace2Space() enter..\n"); + + j = 0; + for ( i = 0; in[i]; i++ ) + { + if ( _VIsSpace( in[i] ) ) + { + if ( !spaced ) + { + in[j] = WSP; + spaced = 1; + j++; + } + } + else + { + spaced = 0; + in[j] = in[i]; + j++; + } + } + + + in[j] = '\0'; + + return j; +} + + +/** + * vFindBase64() returns the integer repesentation of the location in base64 table. + * + * @param in a character + * @return int The base64 table location of input character + */ +static int __VFindBase64( char in ) +{ + int i; + + //DLOG( "__VFindBase64() enter..\n"); + + for ( i = 0; i < 65; i++ ) + { + if ( Base64Table[i] == in ) + return i; + } + return -1; +} + + + +/** + * vBase64Check() returns the total length of input except non-base64 value. + * + * @param in char values which are base64 or non-base64 + * @return int the total length of input except non-base64 + */ +static int __VBase64Check( char *in ) +{ + int i = 0, j = 0; + int base; + + //DLOG( "__VBase64Check() enter..\n"); + + while ( in[i] ) + { + base = __VFindBase64( in[i] ); + if ( base < 0 ) + { + i++; + } + else + { + in[j] = in[i]; + j++; i++; + } + } + + in[j] = '\0'; + + return j; +} + +/** + * vBase64Decoder() decodes the base64 encoded input. + * + * @param Src Base64 encoded input + * @param Dest The destination buffer of decoded value + * @return int The total length decoded value + */ + int +_VB64Decode( char *Dest, char *Src ) +{ + char* Encoded = Src; + int i, j = 0; + int res; + char Base = 0; + char DecodeTemp; + char Debuffer[4] = {0x00, 0x00, 0x00, '\0'}; + int index = 0; + int len; + + //DLOG( "_VB64Decode() enter..\n"); + + len = __VBase64Check( Src ); + + while ( *Encoded ) + { + for ( i = 0; i < 3; i++ ) + Debuffer[i] = 0x00; + + for ( i = 0; i < 4; i++, Encoded++, j++ ) + { + if(*Encoded == 0x00) break; + if((res = __VFindBase64(*Encoded)) < 0) continue; + + Base = ( char )res; + DecodeTemp = 0x00; + + if(Base == 64) { + Encoded++; + break; + } + + switch ( i ) + { + case 0: + DecodeTemp = Base << 2; + Debuffer[0] |= DecodeTemp; + break; + case 1: + DecodeTemp = Base >> 4; + Debuffer[0] |= DecodeTemp; + DecodeTemp = Base << 4; + Debuffer[1] |= DecodeTemp; + break; + case 2: + DecodeTemp = Base >> 2; + Debuffer[1] |= DecodeTemp; + DecodeTemp = Base << 6; + Debuffer[2] |= DecodeTemp; + break; + case 3: + DecodeTemp = Base; + Debuffer[2] |= DecodeTemp; + break; + } + } + + if ( Base == 64 ) + { + switch ( i ) + { + case 0: break; + case 1: + case 2: + Dest[index] = Debuffer[0]; + index++; + break; + case 3: + Dest[index++] = Debuffer[0]; + Dest[index++] = Debuffer[1]; + break; + } + } + else + { + Dest[index++] = Debuffer[0]; + Dest[index++] = Debuffer[1]; + Dest[index++] = Debuffer[2]; + } + } + + return index; +} + + +/** + * vBase64Encoder() encode the input to base64. + * + * @param Src non-base64 char input + * @param Dest The destination buffer of encoded value + * @return 0 + */ +int _VB64Encode( char *Dest, char *Src, int len ) +{ + char* Encoded = Dest; + char* Decoded = Src; + int i, j; + int index; + int res = 0; + int base1 = 0, base2 = 0; + char Enbuffer[4] = {0}; + char Debuffer[3] = {0}; + int length = 0; + + //DLOG( "_VB64Encode() enter..\n"); + + for ( i = 0; i < len; i++ ) + { + res = i%3; + + switch ( res ) + { + case 0: + Debuffer[0] = *Decoded; + break; + case 1: + Debuffer[1] = *Decoded; + break; + case 2: + Debuffer[2] = *Decoded; + index = ( int )( ( Debuffer[0] & 0xFC ) >> 2 ); + Enbuffer[0] = Base64Table[index]; + base1 = ( int )( ( Debuffer[0] & 0x03 ) << 4 ); + base2 = ( int )( ( Debuffer[1] & 0xF0 ) >> 4 ); + index = ( int )( base1 | base2 ); + Enbuffer[1] = Base64Table[index]; + base1 = ( int )( ( Debuffer[1] & 0x0F ) << 2 ); + base2 = ( int )( ( Debuffer[2] & 0xC0 ) >> 6 ); + index = ( int )( base1 | base2 ); + Enbuffer[2] = Base64Table[index]; + index = ( int )( Debuffer[2] & 0x3F ); + Enbuffer[3] = Base64Table[index]; + + Encoded[length++] = Enbuffer[0]; + Encoded[length++] = Enbuffer[1]; + Encoded[length++] = Enbuffer[2]; + Encoded[length++] = Enbuffer[3]; + + for ( j = 0; j < 3; j++ ) + Debuffer[j] = 0x00; + + break; + } + + Decoded++; + } + + res = i % 3; + + switch ( res ) + { + case 0: + break; + case 1: + index = ( int )( ( Debuffer[0] & 0xFC ) >> 2 ); + Enbuffer[0] = Base64Table[index]; + base1 = ( int )( ( Debuffer[0] & 0x03 ) << 4 ); + base2 = ( int )( ( Debuffer[1] & 0xF0 ) >> 4 ); + index = ( int )( base1 | base2 ); + Enbuffer[1] = Base64Table[index]; + Enbuffer[2] = Base64Table[64]; + Enbuffer[3] = Base64Table[64]; + + Encoded[length++] = Enbuffer[0]; + Encoded[length++] = Enbuffer[1]; + Encoded[length++] = Enbuffer[2]; + Encoded[length++] = Enbuffer[3]; + + break; + case 2: + index = ( int )( ( Debuffer[0] & 0xFC ) >> 2 ); + Enbuffer[0] = Base64Table[index]; + base1 = ( int )( ( Debuffer[0] & 0x03 ) << 4 ); + base2 = ( int )( ( Debuffer[1] & 0xF0 ) >> 4 ); + index = ( int )( base1 | base2 ); + Enbuffer[1] = Base64Table[index]; + base1 = ( int )( ( Debuffer[1] & 0x0F ) << 2 ); + base2 = ( int )( ( Debuffer[2] & 0xC0 ) >> 6 ); + index = ( int )( base1 | base2 ); + Enbuffer[2] = Base64Table[index]; + Enbuffer[3] = Base64Table[64]; + + Encoded[length++] = Enbuffer[0]; + Encoded[length++] = Enbuffer[1]; + Encoded[length++] = Enbuffer[2]; + Encoded[length++] = Enbuffer[3]; + + break; + } + + Encoded[length] = '\0'; + + return 0; +} + + +/** + * vUnfolding() unfold the folded line. + * + * @param string The folded line input + * @return int Total length of unfolded output + */ +int _VUnfolding( char *string ) +{ + unsigned int i, j; + unsigned int len; + + //DLOG( "_VUnfolding() enter..\n"); + + len = strlen( string ); + + for ( i = 0, j = 0; i < len; i++, j++ ) + { + string[j] = string[i]; + + // 12.03.2004 Process garbage character at the end of vcard/vcal + if ( _VIsSpace( string[i] ) && ( i < len-5 ) ) + { + if ( string[i-1] == LF || string[i-1] == CR ) + { + j -= 2; string[i-1] = 0; + } + if ( string[i-2] == LF || string[i-2] == CR ) + { + j -= 1; string[i-2] = 0; + } + } + } + + string[j] = '\0'; + + return j; +} + + +int __VIsNewTypeforOrg( char *pCardRaw, int vType ) +{ + int count=0, i = 0, low=0, high=0, diff=0,vTypeNum; + char strTypeName[50]={0}; + extern const char *pszCalTypeList[]; + //SysDebug(( MID_VDATA, "__VIsNewType() enter..\n")); + + while(1) + { + if(*pCardRaw == CR || *pCardRaw == LF) + pCardRaw++; + else + { + if(*pCardRaw == ';' || *pCardRaw == ':' || count >= 50) + { + break; + } + else + strTypeName[count++] = *pCardRaw++; + } + } + + if(vType == VCALENDAR) + vTypeNum = VCAL_TYPE_NUM; + else + return false; + + for ( low = 0, high = vTypeNum - 1; high >= low; diff < 0 ? ( low = i+1 ) : ( high = i-1 ) ) + { + i = ( low + high ) / 2; + + if(vType == VCALENDAR) + diff = strcmp( pszCalTypeList[i], strTypeName ); + + if ( diff == 0 ) /* success: found it */ + return true; + else if( !strncmp( strTypeName, "X-", 2 )) /* jpds-835 X-NEC-SUMMARY, X-NEC-FILENAME, X-NO, X-CLASS µî ƯÁ¤ Æù¿¡¼­ Áö¿øÇÏ´Â TYPEÀÎ °æ¿ì¿¡ ´ëÇÑ Ã³¸® Ãß°¡ by sohn */ + return true; + } + + //if(count <= 50) return TRUE; + + return false; + + //res = __VCardGetName( strTypeName, (char**)pszCardTypeList, VCARD_TYPE_NUM ); +} + + +/** + * vUnfolding() unfold the folded line. + * + * @param string The folded line input + * @return int Total length of unfolded output + */ + int +_VUnfoldingNoSpec( char *string, int vType ) +{ + unsigned int i, j; + unsigned int len; + + //SysDebug(( MID_VDATA, "_VUnfolding() enter..\n" )); + + len = strlen( string ); + + for ( i = 0, j = 0; i < len; i++, j++ ) + { + string[j] = string[i]; + + if ( ( i < len-5 ) ) + { + if ( string[i] == '=' ) + { + if(string[i+1] == CR && string[i+2] == LF && string[i+3] =='=' ) // quoted printableÀÌ°í, ´ÙÀ½ÁÙ·Î stringÀÌ ¿¬°áµÇ´Â °æ¿ì + { + string[i] = 0; + string[i+1] = 0; + string[i+2] = 0; + j -= 1; + i += 2; + } + // else if(string[i+1] == CR || string[i+1] == LF) // CR À̳ª LF µÑÁß¿¡ ÇÑ°³¸¸ Á¸ÀçÇÏ´Â °æ¿ì + else if(string[i+1] == CR && string[i+2] == LF && __VIsNewTypeforOrg(&string[i+3], vType) == false) //stringÀÌ ¿¬°áµÇ´Â °æ¿ì + { + string[i] = 0; + string[i+1] = 0; + string[i+2] = 0; + j -= 1; + i += 2; + } + } + else if(string[i] ==WSP + ||string[i]==TAB) + { + if(string[i-2] == CR && string[i-1] == LF) + { + string[i] = 0; + string[i-1] = 0; + string[i-2] = 0; + j -= 3; + } + else if(string[i-1] == CR || string[i-1] == LF) // CR À̳ª LF µÑÁß¿¡ ÇÑ°³¸¸ Á¸ÀçÇÏ´Â °æ¿ì + { + string[i] = 0; + string[i-1] = 0; + j -= 2; + } + } + + } + } + + string[j] = '\0'; + + return j; +} + +/** + * vFolding() decodes the base64 encoded input. + * + * @param contentline Original line (unfolded) + * @param Dest The destination buffer of folded result + */ + void +_VFolding( char *result, char *contentline ) +{ + int i = 0; + + //DLOG( "_VFolding() enter..\n"); + + while ( *contentline ) + { + if ( i == 75 ) + { + i = 0; + *result++ = '\r'; + *result++ = '\n'; + *result++ = ' '; + } + + *result++ = *contentline++; + i++; + } + + *result++ = '\0'; +} + + +/** + * vFolding() decodes the base64 encoded input. + * + * @param contentline Original line (unfolded) + * @param Dest The destination buffer of folded result + */ + void +_VFoldingQP( char *result, char *contentline ) +{ + int i = 0; + + //DLOG( "_VFolding() enter..\n"); + + while ( *contentline ) + { + if ( i == 74 ) + { + i = 0; + *result++= '='; + *result++ = '\r'; + *result++ = '\n'; + } + + *result++ = *contentline++; + i++; + } + + *result++ = '\0'; +} + + +/** + * vFolding() decodes the base64 encoded input. + * + * @param contentline Original line (unfolded) + * @param Dest The destination buffer of folded result + */ + void +_VFoldingNoSpace( char *result, char *contentline ) +{ + int i = 0; + + //DLOG( "_VFolding() enter..\n"); + + while ( *contentline ) + { + if ( i == 75 ) + { + i = 0; + *result++ = '\r'; + *result++ = '\n'; + } + + *result++ = *contentline++; + i++; + } + + *result++ = '\0'; +} + + +/** + * vQuotedPrintalbeDecoder() decodes the quoted-printable encoded input. + * + * @param Src Quoted-printable encoded input + * @return int The total length decoded value + */ + int +_VQPDecode( char *src ) +{ + int i = 0, j = 0; + char qp[2]; + char decodedNum; + + //DLOG( "_VQPDecode() enter..\n"); + + while ( src[i] ) + { + if ( src[i] == '=' ) + { + if ( !( _VIsSpace( src[i + 1] ) || ( src[i + 1] == '\r' ) || ( src[i+1] == '\n' ) ) ) + { + if ( src[i + 1] == '0' && ( src[i + 2] == 'D' || src[i +2] == 'd' ) && src[i + 3] == '=' + && src[i + 4] == '0' && ( src[i + 5] == 'A' || src[i + 5] == 'a' ) ) + { + src[j] = '\n'; + j++; + i += 6; + } + else + { + qp[0] = src[i + 1]; + qp[1] = src[i + 2]; + decodedNum = __VHexaDecoder( qp ); + src[j] = decodedNum; + i += 3; j++; + } + } + else + { + i += 3; + } + } + else + { + src[j] = src[i]; + i++; j++; + } + } + + src[j] = '\0'; + + j = _VManySpace2Space( src ); + + return j; +} + + + +/** + * vQuotedPrintableEncoder() decodes the quoted-printalbe encoded input. + * + * @param Src Quoted-printable encoded input + * @param Dest The destination buffer of decoded value + * @return int The total length decoded value + */ + int +_VQPEncode( char *dest, char *src ) +{ + int i = 0, j = 0, k = 0; + char encoded[2] = {0x0f, 0x0f}; + + //DLOG( "_VQPEncode() enter..\n"); + + while ( src[i] /*&& ( src[i] > 0 )*/ ) + { + if ( k == 73 && _VIsSpace( src[i] ) ) + { + if( src[i] == WSP ) + { + dest[j++] = '='; dest[j++] = '2'; dest[j++] = '0'; + k += 3; + } + else if ( src[i] == TAB ) + { + dest[j++] = '='; dest[j++] = '0'; dest[j++] = '9'; + k += 3; + } + } + /* else if ( k == 76 ) + { + dest[j++] = '='; dest[j++] = WSP; + k = 0; + } */ + else if ( !__VIsPrintable( src[i] ) ) + { + dest[j++] = '='; + encoded[0] &= (src[i] >> 4); + encoded[1] &= (src[i]); + __VHexaEncoder( encoded ); + dest[j++] = encoded[0]; encoded[0] = 0x0f; + dest[j++] = encoded[1]; encoded[1] = 0x0f; + k += 3; + } + else if ( src[i] == '\r' || src[i] == '\n' ) + { + dest[j++] = '='; dest[j++] = '0'; dest[j++] = 'D'; k += 3; + dest[j++] = '='; dest[j++] = '0'; dest[j++] = 'A'; k += 3; + } + else + { + dest[j++] = src[i]; k++; + } + i++; + } + + dest[j] = '\0'; + + return j; +} + + +/** + * vIsPrintable() check whether the input is printable. + * + * @param in + * @return true/false if input is printable :true else : false + */ +static int __VIsPrintable( char in ) +{ + //DLOG( "__VIsPrintable() enter..\n"); + + if ( in >= 33 && in <= 60 ) return true; + else if ( in >= 62 && in <= 126 ) return true; + else if ( in == WSP || in == TAB ) return true; + else if ( in == '\r' || in == '\n' ) return true; + else return false; +} + + + +/** + * vHexaDecoder() output the character value of inputed hexadecimal value. + * + * @param qp Hexadecimal input value + * @return char Character representation of input hexadecimal value + */ +static char __VHexaDecoder( char *qp ) +{ + int i; + char decoded[2] = {0x00, 0x00}; + char res; + + //DLOG( "__VHexaDecoder() enter..\n"); + + for ( i = 0; i < 2; i++ ) + { + switch ( qp[i] ) + { + case '0': + decoded[i] = 0x00; + break; + case '1': + decoded[i] = 0x01; + break; + case '2': + decoded[i] = 0x02; + break; + case '3': + decoded[i] = 0x03; + break; + case '4': + decoded[i] = 0x04; + break; + case '5': + decoded[i] = 0x05; + break; + case '6': + decoded[i] = 0x06; + break; + case '7': + decoded[i] = 0x07; + break; + case '8': + decoded[i] = 0x08; + break; + case '9': + decoded[i] = 0x09; + break; + case 'a': + case 'A': + decoded[i] = 0x0a; + break; + case 'b': + case 'B': + decoded[i] = 0x0b; + break; + case 'c': + case 'C': + decoded[i] = 0x0c; + break; + case 'd': + case 'D': + decoded[i] = 0x0d; + break; + case 'e': + case 'E': + decoded[i] = 0x0e; + break; + case 'f': + case 'F': + decoded[i] = 0x0f; + break; + } + } + + res = ( char )( ( decoded[0] << 4 ) + decoded[1] ); + + return res; +} + + + +/** + * vHexaEncoder() output the hexadecimal value of input character value. + * + * @return qp Character representation of input hexadecimal value + */ +static void __VHexaEncoder( char *qp ) +{ + int i; + + //DLOG( "__VHexaEncoder() enter..\n"); + + for ( i = 0; i < 2; i++ ) + { + switch ( qp[i] ) + { + case 0: + qp[i] = '0'; + break; + case 1: + qp[i] = '1'; + break; + case 2: + qp[i] = '2'; + break; + case 3: + qp[i] = '3'; + break; + case 4: + qp[i] = '4'; + break; + case 5: + qp[i] = '5'; + break; + case 6: + qp[i] = '6'; + break; + case 7: + qp[i] = '7'; + break; + case 8: + qp[i] = '8'; + break; + case 9: + qp[i] = '9'; + break; + case 10: + qp[i] = 'A'; + break; + case 11: + qp[i] = 'B'; + break; + case 12: + qp[i] = 'C'; + break; + case 13: + qp[i] = 'D'; + break; + case 14: + qp[i] = 'E'; + break; + case 15: + qp[i] = 'F'; + break; + } + } + +} + +/** + * _VIsCrLf() returns one if char is either a space, tab, or newline. + * + * @param s1 [in] pointer to first string. + * @param s2 [in] pointer to second string. + * @return 1 'in' is a space character. + * @return 0 'in' is not a space. + */ + int +_VIsCrLf(char in) +{ + //SysDebug(( MID_VDATA, "_VIsCrLf() enter..\n" )); + + if ( ( in == CR ) || ( in == LF ) ) + { + return 1; + } + else + { + return 0; + } +} + +/* + * vManySpace2Space() converts multiple spaces to single space in 'in'. + * + * @param in [inout] pointer to string. + * @return int length of converted string. + */ + int +_VManyCRLF2CRLF(char *pIn) +{ + int i, j; + bool bCrLf = false, bFirstCrLf = true; + + //SysDebug(( MID_VDATA, "_VManySpace2Space() enter..\n" )); + + j = 0; + for ( i = 0; pIn[i]; i++ ) + { + if ( _VIsCrLf( pIn[i] ) && _VIsCrLf( pIn[i+1] )) + { + if( bFirstCrLf && !bCrLf) + { + bCrLf = 1; + } + else if( !bFirstCrLf ) + { + if ( !bCrLf ) + { + pIn[j] = CR; + pIn[++j] = LF; + bCrLf = true; + j++; + } + } + i++; + } + else + { + bCrLf = false; + bFirstCrLf = false; + pIn[j] = pIn[i]; + j++; + } + } + + pIn[j] = '\0'; + + return j; +} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/cals-ical.c b/src/cals-ical.c new file mode 100755 index 0000000..d708255 --- /dev/null +++ b/src/cals-ical.c @@ -0,0 +1,198 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "cals-typedef.h" +#include "cals-ical-codec.h" +#include "cals-ical.h" +#include "cals-utils.h" +#include "cals-db.h" +#include "cals-internal.h" +#include "cals-schedule.h" + + +#define VCALENDAR_HEADER "BEGIN:VCALENDAR" +#define VNOTE_HEADER "BEGIN:VNOTE" + +bool cal_convert_cal_data_to_vdata_file(const cal_sch_full_t *sch_array, + const int sch_count, const char *file_path, int *error_code) +{ + CALS_FN_CALL; + bool is_success = false; + char *vcal = NULL; + + cal_vCal_ver_t version = CAL_VCAL_VER_1_0; + + retvm_if(NULL == error_code, false, "The error_code is NULL"); + if (NULL == sch_array || NULL == file_path) { + ERR("Invalid ARG:sch_array(%p), file_path(%p)", sch_array, file_path); + *error_code = CAL_ERR_ARG_INVALID; + return false; + } + + // create a vcal file + FILE* file = fopen(file_path, "w+"); + retex_if(file == NULL, *error_code = CAL_ERR_IO_ERR, "Failed to create file!"); + + // encode a sch data + /*if (sch_array[0].cal_type == CAL_EVENT_MEMO_TYPE) + { + is_success = _cal_convert_note_to_vnote(sch_array, sch_count, &vcal, version); + retex_if(is_success == true, *error_code = CAL_ERR_VOBJECT_FAILED, "_cal_convert_sch_to_vcalendar error!"); + } + else*/ + { + is_success = _cal_convert_sch_to_vcalendar(sch_array, sch_count, &vcal, version); + retex_if(is_success != true, *error_code = CAL_ERR_VOBJECT_FAILED, "_cal_convert_sch_to_vcalendar error!"); + } + + retex_if(vcal == NULL, *error_code = CAL_ERR_VOBJECT_FAILED,"cal_convert_cal_data_to_vdata_file vcal is NULL!!"); + + + CALS_DBG( "\n%s\n", vcal ); + + CALS_DBG("------------begint to write to file_path = %s--------------------\n", file_path); + + // write vcal string to file + if (fputs( vcal, file) == EOF) + { + fclose( file ); + + CAL_FREE(vcal); + + *error_code = CAL_ERR_IO_ERR; + return false; + } + + CALS_DBG("------------success write to file_path = %s--------------------\n", file_path); + + // free buff + free(vcal); + fclose( file ); + + return true; + +CATCH: + if (file != NULL) + { + fclose( file ); + } + return false; +} + +bool cal_convert_vdata_file_to_cal_data(const char *file_path, + cal_sch_full_t **sch_array, int * sch_count, int *error_code) +{ + char raw_data[VCALENDAR_DATA_LEN + 1]; + bool is_success = false; + + retvm_if(NULL == error_code, false, "The error_code is NULL"); + + if (NULL == file_path || NULL == sch_array || NULL == sch_count) { + ERR("Invalid ARG:file_path(%p), sch_array(%p), sch_count(%p)", + file_path, sch_array, sch_count); + *error_code = CAL_ERR_ARG_INVALID; + return false; + } + + memset(raw_data, 0, VCALENDAR_DATA_LEN + 1); + + // write vcal to file + FILE * file = fopen(file_path, "r"); + retex_if(file == NULL, *error_code = CAL_ERR_IO_ERR, "Failed to open file!"); + + // Fix for prevent - B. + fread(raw_data, 1, (VCALENDAR_DATA_LEN), file); + + fclose( file ); + + if (strncmp(raw_data, VCALENDAR_HEADER, strlen(VCALENDAR_HEADER)) == 0) + { + // this is a vcalendar stream + is_success = _cal_convert_vcalendar_to_cal_data(raw_data, sch_array, sch_count); + retex_if(is_success == false, *error_code = CAL_ERR_VOBJECT_FAILED, "_cal_convert_vcalendar_to_cal_data error!"); + + } + else + { + ERR( "\n-------------------------- header error --------- -------------\n"); + return false; + } + return true; + +CATCH: + + return false; +} + +int cal_vcalendar_register_vcs_file(const char * file_name) +{ + int ret, i = 0; + bool is_success = false; + cal_sch_full_t * sch_array = NULL; + int sch_count = 0; + int error_code = 0; + int index = 0; + is_success = cal_convert_vdata_file_to_cal_data( file_name, &sch_array, &sch_count, &error_code); + retex_if(!is_success,,"[ERROR]Falied to convert to cal!\n"); + + // get data + if ((sch_array != NULL) && (sch_count != 0)) + { + CALS_DBG("\n-------------------------get a sch from vcalendar ---------------------------------\n"); + + calendar_svc_connect(); + + for ( i = 0; i < sch_count; i++) + { + CALS_DBG("\n--------------------------begin to store it in DB--------------------------------\n"); + if (sch_array[i].cal_type == CAL_EVENT_TODO_TYPE) + ret = cals_insert_schedule(sch_array + i); + else + ret = cals_insert_schedule(sch_array + i); + retvm_if(ret < CAL_SUCCESS, ret, "cals_insert_schedule() Failed(%d)", ret); + index = ret; + + CALS_DBG("\n--------------------------success store it in DB--------------------------------\n"); + } + + } + + if ( sch_array != NULL ) + { + cal_db_service_free_full_record(sch_array,&error_code); + CAL_FREE(sch_array); + } + + CALS_DBG("-----------------exit-cal_vcalendar_register_vcs_file-------------------\n"); + calendar_svc_close(); + return index; + +CATCH: + + calendar_svc_close(); + + if ( sch_array != NULL ) + { + cal_db_service_free_full_record(sch_array,&error_code); + CAL_FREE(sch_array); + } + + return -1; +} + + diff --git a/src/cals-ical.h b/src/cals-ical.h new file mode 100755 index 0000000..02bc23c --- /dev/null +++ b/src/cals-ical.h @@ -0,0 +1,79 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_ICAL_H__ +#define __CALENDAR_SVC_ICAL_H__ +/** +* @ingroup app_engine +* @addtogroup app_cal_engine +* @{ +*/ + +#define TM_YEAR_BASE 1900 +#define VCALENDAR_TIME_STR_LEN 16 +#define VCALENDAR_DATA_LEN 3000 + +#define SCH_LIST_LEN 10 + +//#include "org-engine-typedef.h" + +/** +* @fn bool cal_convert_cal_data_to_vdata_file( const cal_sch_full_t * sch_array, const int sch_count, const char * file_path, int * error_code); +* This function convert a record to vcal file. +* +* @return This function returns true on success, or false on failure. +* @param[in] sch_array Points the field information for schedule table' s record. +* @param[in] sch_count Points the count of records. +* @param[in] file_path Points the file path. +* @param[out] error_code Points the error code. +* @exception #CAL_ERR_VOBJECT_FAILED - Encode vcal error. +* @exception #CAL_ERR_FILE_CREATE_ERROR - Create file error. +* @exception #CAL_ERR_FILE_WRITINGNG_ERROR - Write file error. +*/ +bool cal_convert_cal_data_to_vdata_file( const cal_sch_full_t * sch_array, const int sch_count, const char * file_path, int * error_code); + +/** +* @fn bool cal_convert_vdata_file_to_cal_data(const char * file_path, cal_sch_full_t ** sch_array, int * sch_count, int* error_code ); +* This function convert a record to vcal file. +* +* @return This function returns true on success, or false on failure. +* @param[in] file_path Points the file path. +* @param[out] sch_array Points the field information for schedule table' s record. +* @param[out] sch_count Points the count of records. +* @param[out] error_code Points the error code. +* @exception #CAL_ERR_FILE_OPEN_ERROR - Open file error. +* @exception #CAL_ERR_VOBJECT_FAILED - Decode vcal error. +*/ +bool cal_convert_vdata_file_to_cal_data(const char * file_path, cal_sch_full_t ** sch_array, int * sch_count, int *error_code ); + +/** +* @fn int cal_vcalendar_register_vcs_file(const char * file_name); +* This function make vcal file by record index. +* +* @return This function returns true on success, or false on failure. +* @param[in] file_name vcalendar's file name +* @exception #CAL_ERR_FILE_OPEN_ERROR - Open file error. +* @exception #CAL_ERR_VOBJECT_FAILED - Decode vcal error. +* @exception #CAL_ERR_DB_NOT_OPENED - org db not opended. +*/ +int cal_vcalendar_register_vcs_file(const char * file_name); + +/** +* @} +*/ +#endif /* __CALENDAR_SVC_ICAL_H__ */ diff --git a/src/cals-inotify.c b/src/cals-inotify.c new file mode 100755 index 0000000..d02844d --- /dev/null +++ b/src/cals-inotify.c @@ -0,0 +1,340 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include + +#include "cals-internal.h" +#include "cals-typedef.h" + +typedef struct +{ + int wd; + void (*cb)(void *); + void *cb_data; +}noti_info; + +static int inoti_fd = -1; +static guint inoti_handler; +static GSList *noti_list; + +static inline void _handle_callback(GSList *noti_list, int wd, uint32_t mask) +{ + noti_info *noti; + GSList *it = NULL; + + for (it = noti_list;it;it=it->next) + { + noti = (noti_info *)it->data; + if (noti->wd == wd) { + if ((mask & IN_CLOSE_WRITE) && noti->cb) + noti->cb(noti->cb_data); + } + } +} + +static gboolean _inotify_gio_cb(GIOChannel *src, GIOCondition cond, gpointer data) +{ + int fd, ret; + struct inotify_event ie; + char name[FILENAME_MAX]; + + fd = g_io_channel_unix_get_fd(src); + + while (0 < (ret = read(fd, &ie, sizeof(ie)))) { + if (sizeof(ie) == ret) { + if (noti_list) + _handle_callback(noti_list, ie.wd, ie.mask); + + while (0 < ie.len) { + ret = read(fd, name, (ie.lennext) + { + if (it->data) + { + same_noti = it->data; + if (same_noti->wd == wd && same_noti->cb == cb && same_noti->cb_data == data) { + break; + } + else { + same_noti = NULL; + } + } + } + + if (same_noti) { + _inotify_watch(inoti_fd, path); + ERR("The same callback(%s) is already exist", path); + return CAL_ERR_ALREADY_EXIST; + } + + ret = _inotify_watch(inoti_fd, path); + retvm_if(CAL_SUCCESS != ret, ret, "_inotify_watch() Failed"); + + noti = calloc(1, sizeof(noti_info)); + retvm_if(NULL == noti, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed"); + + noti->wd = wd; + noti->cb_data = data; + noti->cb = cb; + noti_list = g_slist_append(noti_list, noti); + + return CAL_SUCCESS; +} + +static inline int _del_noti_with_data(GSList **noti_list, int wd, + void (*cb)(void *), void *user_data) +{ + int del_cnt, remain_cnt; + GSList *it, *result; + + del_cnt = 0; + remain_cnt = 0; + + it = result = *noti_list; + while (it) + { + noti_info *noti = it->data; + if (noti && wd == noti->wd) + { + if (cb == noti->cb && user_data == noti->cb_data) { + it = it->next; + result = g_slist_remove(result , noti); + free(noti); + del_cnt++; + continue; + } + else { + remain_cnt++; + } + } + it = it->next; + } + retvm_if(del_cnt == 0, CAL_ERR_NO_DATA, "nothing deleted"); + + *noti_list = result; + + return remain_cnt; +} + +static inline int _del_noti(GSList **noti_list, int wd, void (*cb)(void *)) +{ + int del_cnt, remain_cnt; + GSList *it, *result; + + del_cnt = 0; + remain_cnt = 0; + + it = result = *noti_list; + while (it) + { + noti_info *noti = it->data; + if (noti && wd == noti->wd) + { + if (NULL == cb || noti->cb == cb) { + it = it->next; + result = g_slist_remove(result, noti); + free(noti); + del_cnt++; + continue; + } + else { + remain_cnt++; + } + } + it = it->next; + } + retvm_if(del_cnt == 0, CAL_ERR_NO_DATA, "nothing deleted"); + + *noti_list = result; + + return remain_cnt; +} + +int cals_inotify_unsubscribe(const char *path, void (*cb)(void *)) +{ + int ret, wd; + + retv_if(NULL == path, CAL_ERR_ARG_NULL); + retvm_if(inoti_fd < 0, CAL_ERR_ENV_INVALID, + "inoti_fd(%d) is invalid", inoti_fd); + + wd = _inotify_get_wd(inoti_fd, path); + retvm_if(-1 == wd, CAL_ERR_INOTIFY_FAILED, + "_inotify_get_wd() Failed(%d)", errno); + + ret = _del_noti(¬i_list, wd, cb); + warn_if(ret < CAL_SUCCESS, "_del_noti() Failed(%d)", ret); + + if (0 == ret) + return inotify_rm_watch(inoti_fd, wd); + + return _inotify_watch(inoti_fd, path); +} + +int cals_inotify_unsubscribe_with_data(const char *path, + void (*cb)(void *), void *user_data) +{ + int ret, wd; + + retv_if(NULL==path, CAL_ERR_ARG_NULL); + retv_if(NULL==cb, CAL_ERR_ARG_NULL); + retvm_if(inoti_fd < 0, CAL_ERR_ENV_INVALID, + "inoti_fd(%d) is invalid", inoti_fd); + + wd = _inotify_get_wd(inoti_fd, path); + retvm_if(-1 == wd, CAL_ERR_INOTIFY_FAILED, + "_inotify_get_wd() Failed(%d)", errno); + + ret = _del_noti_with_data(¬i_list, wd, cb, user_data); + warn_if(ret < CAL_SUCCESS, "_del_noti_with_data() Failed(%d)", ret); + + if (0 == ret) + return inotify_rm_watch(inoti_fd, wd); + + return _inotify_watch(inoti_fd, path); +} + +static void _clear_nslot_list(gpointer data, gpointer user_data) +{ + free(data); +} + +static inline gboolean _inotify_detach_handler(guint id) +{ + return g_source_remove(id); +} + +void cals_inotify_close(void) +{ + if (inoti_handler) { + _inotify_detach_handler(inoti_handler); + inoti_handler = 0; + } + + if (noti_list) { + g_slist_foreach(noti_list, _clear_nslot_list, NULL); + g_slist_free(noti_list); + noti_list = NULL; + } + + if (0 <= inoti_fd) { + close(inoti_fd); + inoti_fd = -1; + } +} diff --git a/src/cals-inotify.h b/src/cals-inotify.h new file mode 100755 index 0000000..7f1d839 --- /dev/null +++ b/src/cals-inotify.h @@ -0,0 +1,30 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_INOTIFY_H__ +#define __CALENDAR_SVC_INOTIFY_H__ + +int cals_inotify_init(void); +void cals_inotify_close(void); +int cals_inotify_subscribe(const char *path, void (*cb)(void *), void *data); +int cals_inotify_unsubscribe(const char *path, void (*cb)(void *)); +int cals_inotify_unsubscribe_with_data(const char *path, + void (*cb)(void *), void *user_data); + + +#endif //__CALENDAR_SVC_INOTIFY_H__ \ No newline at end of file diff --git a/src/cals-provider.c b/src/cals-provider.c new file mode 100755 index 0000000..a4f5ba3 --- /dev/null +++ b/src/cals-provider.c @@ -0,0 +1,3095 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-utils.h" +#include "cals-db.h" +#include "cals-db-info.h" +#include "cals-ical.h" +#include "cals-tz-utils.h" +#include "cals-recurrence-utils.h" +#include "cals-ical-codec.h" +#include "cals-alarm.h" +#include "cals-sqlite.h" +#include "cals-calendar.h" +#include "cals-schedule.h" +#include "cals-inotify.h" + +extern sqlite3* calendar_db_handle; + +static int db_ref_cnt = 0; +cal_svc_tm_info_t cal_svc_tm_value; + +typedef enum +{ + VALUE_TYPE_TEXT, + VALUE_TYPE_INT, + VALUE_TYPE_TIME, + VALUE_TYPE_DOUBLE, + VALUE_TYPE_USER, +} cal_value_type_t; + +typedef struct +{ + char *field_name; + int type; +} __cal_field_type; + +static const __cal_field_type __calendar_event_type_field[]={ + {CAL_VALUE_INT_INDEX, VALUE_TYPE_INT}, + {CAL_VALUE_INT_ACCOUNT_ID, VALUE_TYPE_INT}, + {CAL_VALUE_TXT_SUMMARY, VALUE_TYPE_TEXT}, + {CAL_VALUE_TXT_DESCRIPTION, VALUE_TYPE_TEXT}, + {CAL_VALUE_TXT_LOCATION, VALUE_TYPE_TEXT}, + {CAL_VALUE_INT_ALL_DAY_EVENT, VALUE_TYPE_INT}, + {CAL_VALUE_GMT_START_DATE_TIME, VALUE_TYPE_TIME}, + {CAL_VALUE_GMT_END_DATE_TIME, VALUE_TYPE_TIME}, + {CAL_VALUE_INT_REPEAT_TERM, VALUE_TYPE_INT}, + {CAL_VALUE_INT_REPEAT_INTERVAL, VALUE_TYPE_INT}, + {CAL_VALUE_INT_REPEAT_OCCURRENCES, VALUE_TYPE_INT}, + {CAL_VALUE_GMT_REPEAT_END_DATE, VALUE_TYPE_TIME}, + {CAL_VALUE_INT_SUN_MOON, VALUE_TYPE_INT}, + {CAL_VALUE_INT_WEEK_START, VALUE_TYPE_INT}, + {CAL_VALUE_TXT_WEEK_FLAG, VALUE_TYPE_TEXT}, + {CAL_VALUE_INT_DAY_DATE, VALUE_TYPE_INT}, + {CAL_VALUE_GMT_LAST_MODIFIED_TIME, VALUE_TYPE_TIME}, + {CAL_VALUE_INT_MISSED, VALUE_TYPE_INT}, + {CAL_VALUE_INT_TASK_STATUS, VALUE_TYPE_INT}, + {CAL_VALUE_INT_PRIORITY, VALUE_TYPE_INT}, + {CAL_VALUE_INT_TIMEZONE, VALUE_TYPE_INT}, + {CAL_VALUE_INT_FILE_ID, VALUE_TYPE_INT}, + {CAL_VALUE_INT_CONTACT_ID, VALUE_TYPE_INT}, + {CAL_VALUE_INT_BUSY_STATUS, VALUE_TYPE_INT}, + {CAL_VALUE_INT_SENSITIVITY, VALUE_TYPE_INT}, + {CAL_VALUE_INT_MEETING_STATUS, VALUE_TYPE_INT}, + {CAL_VALUE_TXT_UID, VALUE_TYPE_TEXT}, + {CAL_VALUE_TXT_ORGANIZER_NAME, VALUE_TYPE_TEXT}, + {CAL_VALUE_TXT_ORGANIZER_EMAIL, VALUE_TYPE_TEXT}, + {CAL_VALUE_INT_CALENDAR_TYPE, VALUE_TYPE_INT}, + {CAL_VALUE_TXT_GCAL_ID, VALUE_TYPE_TEXT}, + {CAL_VALUE_INT_DELETED, VALUE_TYPE_INT}, + {CAL_VALUE_TXT_UPDATED, VALUE_TYPE_TEXT}, + {CAL_VALUE_INT_LOCATION_TYPE, VALUE_TYPE_INT}, + {CAL_VALUE_TXT_LOCATION_SUMMARY, VALUE_TYPE_TEXT}, + {CAL_VALUE_TXT_ETAG, VALUE_TYPE_TEXT}, + {CAL_VALUE_INT_CALENDAR_ID, VALUE_TYPE_INT}, + {CAL_VALUE_INT_SYNC_STATUS, VALUE_TYPE_INT}, + {CAL_VALUE_TXT_EDIT_URL, VALUE_TYPE_TEXT}, + {CAL_VALUE_TXT_GEDERID, VALUE_TYPE_TEXT}, + {CAL_VALUE_INT_DST, VALUE_TYPE_INT}, + {CAL_VALUE_INT_ORIGINAL_EVENT_ID, VALUE_TYPE_INT}, + {CAL_VALUE_INT_CALENDAR_INDEX, VALUE_TYPE_INT}, + {CAL_VALUE_DBL_LATITUDE, VALUE_TYPE_DOUBLE}, + {CAL_VALUE_DBL_LONGITUDE, VALUE_TYPE_DOUBLE}, + {CAL_VALUE_TXT_TZ_NAME, VALUE_TYPE_TEXT}, + {CAL_VALUE_TXT_TZ_CITY_NAME, VALUE_TYPE_TEXT}, + {CAL_VALUE_INT_EMAIL_ID, VALUE_TYPE_INT}, + {CAL_VALUE_INT_AVAILABILITY, VALUE_TYPE_INT}, + {CAL_VALUE_TXT_MEETING_CATEGORY_DETAIL_NAME, VALUE_TYPE_TEXT}, + {CAL_VALUE_GMT_CREATED_DATE_TIME, VALUE_TYPE_TIME}, + {CAL_VALUE_GMT_COMPLETED_DATE_TIME, VALUE_TYPE_TIME}, + {CAL_VALUE_INT_PROGRESS, VALUE_TYPE_INT}, + {NULL, VALUE_TYPE_USER} +}; + +static const __cal_field_type __calendar_table_field[] = { + {CAL_TABLE_INT_INDEX, VALUE_TYPE_INT}, + {CAL_TABLE_TXT_CALENDAR_ID, VALUE_TYPE_TEXT}, + {CAL_TABLE_TXT_UID, VALUE_TYPE_TEXT}, + {CAL_TABLE_TXT_LINK, VALUE_TYPE_TEXT}, + {CAL_TABLE_INT_UPDATED, VALUE_TYPE_INT}, + {CAL_TABLE_TXT_NAME, VALUE_TYPE_TEXT}, + {CAL_TABLE_TXT_DESCRIPTION, VALUE_TYPE_TEXT}, + {CAL_TABLE_TXT_AUTHOR, VALUE_TYPE_TEXT}, + {CAL_TABLE_TXT_COLOR, VALUE_TYPE_TEXT}, + {CAL_TABLE_INT_HIDDEN, VALUE_TYPE_INT}, + {CAL_TABLE_INT_SELECTED, VALUE_TYPE_INT}, + {CAL_TABLE_TXT_LOCATION, VALUE_TYPE_TEXT}, + {CAL_TABLE_INT_LOCALE, VALUE_TYPE_INT}, + {CAL_TABLE_INT_COUNTRY, VALUE_TYPE_INT}, + {CAL_TABLE_INT_TIME_ZONE, VALUE_TYPE_INT}, + {CAL_TABLE_TXT_TIME_ZONE_LABEL, VALUE_TYPE_TEXT}, + {CAL_TABLE_INT_DISPLAY_ALL_TIMEZONES, VALUE_TYPE_INT}, + {CAL_TABLE_INT_DATE_FIELD_ORDER, VALUE_TYPE_INT}, + {CAL_TABLE_INT_FROMAT_24HOUR_TIME, VALUE_TYPE_INT}, + {CAL_TABLE_INT_WEEK_START, VALUE_TYPE_INT}, + {CAL_TABLE_INT_DEFAULT_CAL_MODE, VALUE_TYPE_INT}, + {CAL_TABLE_INT_CUSTOM_CAL_MODE, VALUE_TYPE_INT}, + {CAL_TABLE_TXT_USER_LOCATION, VALUE_TYPE_TEXT}, + {CAL_TABLE_TXT_WEATHER, VALUE_TYPE_TEXT}, + {CAL_TABLE_INT_SHOW_DECLINED_EVENTS, VALUE_TYPE_INT}, + {CAL_TABLE_INT_HIDE_INVITATIONS, VALUE_TYPE_INT}, + {CAL_TABLE_INT_ALTERNATE_CALENDAR, VALUE_TYPE_INT}, + {CAL_TABLE_INT_VISIBILITY, VALUE_TYPE_INT}, + {CAL_TABLE_INT_PROJECTION, VALUE_TYPE_INT}, + {CAL_TABLE_INT_SEQUENCE, VALUE_TYPE_INT}, + {CAL_TABLE_INT_SUPRESS_REPLY_NOTIFICATIONS,VALUE_TYPE_INT}, + {CAL_TABLE_INT_SYNC_EVENT, VALUE_TYPE_INT}, + {CAL_TABLE_INT_TIMES_CLEANED, VALUE_TYPE_INT}, + {CAL_TABLE_INT_GUESTS_CAN_MODIFY, VALUE_TYPE_INT}, + {CAL_TABLE_INT_GUESTS_CAN_INVITE_OTHERS,VALUE_TYPE_INT}, + {CAL_TABLE_INT_GUESTS_CAN_SEE_GUESTS, VALUE_TYPE_INT}, + {CAL_TABLE_INT_ACCESS_LEVEL, VALUE_TYPE_INT}, + {CAL_TABLE_INT_SYNC_STATUS, VALUE_TYPE_INT}, + {CAL_TABLE_INT_ACCOUNT_ID, VALUE_TYPE_INT}, + {CAL_TABLE_INT_SENSITIVITY, VALUE_TYPE_INT}, + {NULL,VALUE_TYPE_USER} +}; + + +static const __cal_field_type __timezone_table_field[] = { + + {CAL_TZ_VALUE_INT_INDEX, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_TZ_OFFSET, VALUE_TYPE_INT}, + + {CAL_TZ_VALUE_TXT_STD_NAME, VALUE_TYPE_TEXT}, + {CAL_TZ_VALUE_INT_STD_START_MONTH, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_STD_START_POSITION_OF_WEEK, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_STD_START_DAY, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_STD_START_HOUR, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_STD_BIAS, VALUE_TYPE_INT}, + + {CAL_TZ_VALUE_TXT_DST_NAME, VALUE_TYPE_TEXT}, + {CAL_TZ_VALUE_INT_DST_START_MONTH, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_DST_START_POSITION_OF_WEEK, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_DST_START_DAY, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_DST_START_HOUR, VALUE_TYPE_INT}, + {CAL_TZ_VALUE_INT_DST_BIAS, VALUE_TYPE_INT}, + + {NULL,VALUE_TYPE_USER} +}; + +static cal_value_type_t __calendar_svc_get_type(int type, const char *field) +{ + + int index = 0; + const __cal_field_type *field_table; + + if((type == CAL_STRUCT_TYPE_SCHEDULE)||(type == CAL_STRUCT_TYPE_TODO)) + field_table = __calendar_event_type_field; + else if(type == CAL_STRUCT_TYPE_CALENDAR) + field_table = __calendar_table_field; + else //(type == CAL_STRUCT_TYPE_TIMEZONE) + field_table = __timezone_table_field; + + index = 0; + while ((field_table[index].field_name != NULL) && + (strcmp(field_table[index].field_name, field)!=0)) + { + index++; + } + + return field_table[index].type; +} + +API int calendar_svc_connect(void) +{ + CALS_FN_CALL; + int ret = 0; + + if(db_ref_cnt <= 0) + { + ret = cals_db_open(); + retvm_if(ret, ret, "cals_db_open() Failed(%d)", ret); + + ret = cals_inotify_init(); + if(CAL_SUCCESS != ret) { + cals_db_close(); + ERR("cals_inotify_init() Failed(%d)", ret); + return ret; + } + db_ref_cnt = 0; + } + db_ref_cnt++; + + return CAL_SUCCESS; +} + +API int calendar_svc_close(void) +{ + CALS_FN_CALL; + retvm_if(0 == db_ref_cnt, CAL_ERR_ENV_INVALID, + "Calendar service was not connected"); + + if (db_ref_cnt==1) { + cals_db_close(); + cals_inotify_close(); + } + db_ref_cnt--; + + return CAL_SUCCESS; +} + + +API int calendar_svc_subscribe_db_change(const char *noti_type, void(*calendarNotiCb)(void *), void *user_data) +{ + CALS_FN_CALL; + int ret; + const char *noti_path; + + retv_if(NULL == noti_type, CAL_ERR_ARG_NULL); + + if(0 == strcmp(noti_type, CAL_STRUCT_SCHEDULE)) + noti_path = cals_noti_get_file_path(CALS_NOTI_TYPE_EVENT); + else if(0 == strcmp(noti_type, CAL_STRUCT_TODO)) + noti_path = cals_noti_get_file_path(CALS_NOTI_TYPE_TODO); + else if(0 == strcmp(noti_type, CAL_STRUCT_CALENDAR)) + noti_path = cals_noti_get_file_path(CALS_NOTI_TYPE_CALENDAR); + else { + ERR("Invalid noti_type(%s)", noti_type); + return CAL_ERR_ARG_INVALID; + } + + ret = cals_inotify_subscribe(noti_path, calendarNotiCb, user_data); + retvm_if(CAL_SUCCESS != ret, ret, "cals_inotify_subscribe() Failed(%d)", ret); + + return CAL_SUCCESS; +} + + +API int calendar_svc_unsubscribe_db_change (const char *noti_type, void(*cb)(void *)) +{ + CALS_FN_CALL; + int ret; + const char *noti_path; + + retv_if(NULL == noti_type, CAL_ERR_ARG_NULL); + retv_if(NULL == cb, CAL_ERR_ARG_NULL); + + if(0 == strcmp(noti_type, CAL_STRUCT_SCHEDULE)) + noti_path = cals_noti_get_file_path(CALS_NOTI_TYPE_EVENT); + else if(0 == strcmp(noti_type, CAL_STRUCT_TODO)) + noti_path = cals_noti_get_file_path(CALS_NOTI_TYPE_TODO); + else if(0 == strcmp(noti_type, CAL_STRUCT_CALENDAR)) + noti_path = cals_noti_get_file_path(CALS_NOTI_TYPE_CALENDAR); + else { + ERR("Invalid noti_type(%s)", noti_type); + return CAL_ERR_ARG_INVALID; + } + + ret = cals_inotify_unsubscribe(noti_path, cb); + retvm_if(CAL_SUCCESS != ret, ret, "cals_inotify_unsubscribe() Failed(%d)", ret); + + return CAL_SUCCESS; +} + +API int calendar_svc_subscribe_change (void(*calendarNotiCb)(void *), void *user_data) +{ + CALS_FN_CALL; + calendar_svc_subscribe_db_change(CAL_STRUCT_SCHEDULE, calendarNotiCb,user_data); + calendar_svc_subscribe_db_change(CAL_STRUCT_TODO, calendarNotiCb,user_data); + return CAL_SUCCESS; +} + +API int calendar_svc_unsubscribe_change (void(*cb)(void *)) +{ + CALS_FN_CALL; + calendar_svc_unsubscribe_db_change(CAL_STRUCT_SCHEDULE, cb); + calendar_svc_unsubscribe_db_change(CAL_STRUCT_TODO, cb); + + return CAL_SUCCESS; +} + +API int calendar_svc_insert(cal_struct *event) +{ + int ret, index = 0; + cal_sch_full_t *sch_temp = NULL; + calendar_t *cal_temp = NULL; + cal_timezone_t * tz_temp = NULL; + clock_t start_time=0,end_time = 0; + + retv_if(NULL == event, CAL_ERR_ARG_NULL); + + start_time = CAL_PROFILE_GET_TIME(); + + ret = cals_begin_trans(); + retvm_if(CAL_SUCCESS != ret, ret, "cals_begin_trans() Failed(%d)", ret); + + switch(event->event_type) { + case CAL_STRUCT_TYPE_SCHEDULE: + sch_temp = (cal_sch_full_t*)event->user_data; + sch_temp->cal_type = CAL_EVENT_SCHEDULE_TYPE; + + ret = cals_insert_schedule(sch_temp); + if (ret < CAL_SUCCESS) { + cals_end_trans(false); + ERR("cals_insert_schedule() Failed(%d)", ret); + return ret; + } + + index = sch_temp->index = ret; + break; + case CAL_STRUCT_TYPE_CALENDAR: + cal_temp = (calendar_t*)event->user_data; + + ret = cals_insert_calendar(cal_temp); + if (ret < CAL_SUCCESS) { + cals_end_trans(false); + ERR("cals_insert_calendar() Failed(%d)", ret); + return ret; + } + + index = cal_temp->index = ret; + break; + case CAL_STRUCT_TYPE_TODO: + sch_temp = (cal_sch_full_t*)event->user_data; + + ret = cals_insert_schedule(sch_temp); + if (ret < CAL_SUCCESS) { + cals_end_trans(false); + ERR("cals_insert_schedule() Failed(%d)", ret); + return ret; + } + + index = sch_temp->index = ret; + break; + case CAL_STRUCT_TYPE_TIMEZONE: + tz_temp = (cal_timezone_t*)event->user_data; + + ret = cals_insert_timezone(tz_temp); + if (ret < CAL_SUCCESS) { + cals_end_trans(false); + ERR("cals_insert_timezone() Failed(%d)", ret); + return ret; + } + + index = tz_temp->index = ret; + break; + default: + cals_end_trans(false); + ERR("Unknown event type(%d)", event->event_type); + return CAL_ERR_ARG_INVALID; + } + cals_end_trans(true); + + end_time = CAL_PROFILE_GET_TIME(); + CAL_PROFILE_PRINT(start_time,end_time); + + return index; +} + + +API int calendar_svc_get(const char *data_type,int index,const char *field_list, cal_struct **record) +{ + CALS_FN_CALL; + int error_code = 0; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + char rearranged[CALS_SQL_MIN_LEN] = {0}; + int rc = 0; + sqlite3_stmt *stmt = NULL; + bool malloc_inside = false; + + retex_if(NULL == data_type,,"data_type is NULL"); + retex_if(NULL == record ,,"record is NULL"); + + if((0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) || (0 == strcmp(data_type,CAL_STRUCT_TODO))) + { + if(NULL == *record) + { + *record = calendar_svc_struct_new(data_type); + retex_if(NULL == *record,,"calendar_svc_struct_new() Failed"); + + malloc_inside = true; + } + + cal_sch_full_t *sch_record = NULL; + sch_record = (*record)->user_data; + + if (field_list) { + cals_rearrage_schedule_field(field_list, rearranged, sizeof(rearranged)); + sprintf(sql_value,"SELECT %s FROM %s WHERE id=%d", + CALS_TABLE_SCHEDULE, rearranged, index); + } else + sprintf(sql_value,"SELECT * FROM %s WHERE id=%d;", CALS_TABLE_SCHEDULE, index); + + stmt = cals_query_prepare(sql_value); + retex_if(NULL == stmt,,"cals_query_prepare() Failed"); + + rc = cals_stmt_step(stmt); + retex_if(CAL_TRUE != rc,,"cals_stmt_step() Failed(%d)", rc); + + if (field_list) + cals_stmt_get_filted_schedule(stmt, sch_record, field_list); + else + cals_stmt_get_full_schedule(stmt, sch_record, true); + + sch_record->index = index; + + if (0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) { + cal_db_service_get_participant_info_by_index(index,&(sch_record->attendee_list),&error_code); + cal_db_service_get_meeting_category_info_by_index(index,&(sch_record->meeting_category),&error_code); + cal_db_service_get_recurrency_exception(index,&(sch_record->exception_date_list),&error_code); + cals_get_alarm_info(index, &(sch_record->alarm_list)); + } + } + else if(0 == strcmp(data_type,CAL_STRUCT_CALENDAR)) + { + if(NULL == *record) + { + *record = calendar_svc_struct_new(CAL_STRUCT_CALENDAR); + retex_if(NULL == *record,,"calendar_svc_struct_new() Failed"); + } + + calendar_t *calendar = NULL; + calendar = (*record)->user_data; + + if (field_list) { + cals_rearrage_calendar_field(field_list, rearranged, sizeof(rearranged)); + sprintf(sql_value,"SELECT rowid,%s FROM %s WHERE rowid=%d", + rearranged, CALS_TABLE_CALENDAR, index); + } + else + sprintf(sql_value,"SELECT rowid,* FROM %s WHERE rowid=%d", + CALS_TABLE_CALENDAR, index); + + stmt = cals_query_prepare(sql_value); + retex_if(NULL == stmt,,"cals_query_prepare() Failed"); + + rc = cals_stmt_step(stmt); + retex_if(CAL_TRUE != rc,,"cals_stmt_step() Failed(%d)", rc); + + if (field_list) + cals_stmt_get_filted_calendar(stmt, calendar, field_list); + else + cals_stmt_get_calendar(stmt, calendar); + + calendar->index = index; + } + else if(0 == strcmp(data_type,CAL_STRUCT_TIMEZONE)) + { + if(NULL == *record) + { + *record = calendar_svc_struct_new(CAL_STRUCT_TIMEZONE); + retex_if(NULL == *record,,"calendar_svc_struct_new() Failed"); + } + + cal_timezone_t *detail_record = NULL; + detail_record = (*record)->user_data; + + /*if(NULL != field_list) - not support yet + { + sprintf(sql_value,"select rowid,%s from timezone_table where rowid=%d;",field_list,index); + } + else*/ + { + sprintf(sql_value,"select rowid,* from timezone_table where rowid=%d;",index); + } + + stmt = cals_query_prepare(sql_value); + retex_if(NULL == stmt,,"cals_query_prepare() Failed"); + + rc = cals_stmt_step(stmt); + retex_if(CAL_TRUE != rc,,"cals_stmt_step() Failed(%d)", rc); + + /*if(NULL != field_list) - not support yet + { + cal_db_service_convert_stmt_to_select_field_tz_info(stmt,detail_record,field_list); + } + else*/ + { + cal_db_service_convert_stmt_to_tz_info(stmt,detail_record); + } + + detail_record->index = index; + } + else + { + retex_if(true,,"Can not find!\n"); + } + + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return CAL_SUCCESS; + +CATCH: + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + if(malloc_inside) + { + if(NULL != *record) + { + calendar_svc_struct_free(record); + } + } + + return CAL_ERR_FAIL; + +} + + +API int calendar_svc_get_count(int account_id, int calendar_id, const char *data_type) +{ + CALS_FN_CALL; + int count = 0; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + char condition_value[CALS_SQL_MIN_LEN] = {0}; + + retv_if(NULL == data_type, CAL_ERR_ARG_NULL); + + if(0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) + { + sprintf(condition_value,"WHERE type=%d",CAL_EVENT_SCHEDULE_TYPE); + + if(account_id == ALL_VISIBILITY_ACCOUNT || calendar_id==ALL_VISIBILITY_ACCOUNT) + { + sprintf(sql_value,"SELECT COUNT(*) FROM %s A, %s B %s " + "AND A.calendar_id = B.rowid AND B.visibility = 1 AND " + "A.is_deleted = 0 ORDER BY A.start_date_time", + CALS_TABLE_SCHEDULE, CALS_TABLE_CALENDAR, condition_value); + } + else + { + if(account_id !=0) + { + sprintf(condition_value,"%s AND account_id = %d",condition_value,account_id); + } + + if(calendar_id != 0) + { + sprintf(condition_value,"%s AND calendar_id = %d",condition_value,calendar_id); + } + + sprintf(sql_value,"SELECT COUNT(*) FROM %s %s AND is_deleted = 0 ORDER BY start_date_time", + CALS_TABLE_SCHEDULE, condition_value); + } + + } + else if(0 == strcmp(data_type,CAL_STRUCT_TODO)) + { + sprintf(condition_value,"WHERE type=%d",CAL_EVENT_TODO_TYPE); + + if(account_id !=0) + { + sprintf(condition_value,"%s AND account_id = %d ",condition_value,account_id); + } + + if(calendar_id != 0) + { + sprintf(condition_value,"%s AND calendar_id = %d ",condition_value,calendar_id); + } + + sprintf(sql_value,"SELECT COUNT(*) FROM %s %s AND is_deleted = 0", + CALS_TABLE_SCHEDULE, condition_value); + + } + else if(0 == strcmp(data_type,CAL_STRUCT_CALENDAR)) + { + condition_value[0] = '\0'; + + if(account_id != 0) + { + sprintf(condition_value, "WHERE account_id = %d ", account_id); + } + + sprintf(sql_value,"SELECT COUNT(*) FROM %s %s;", CALS_TABLE_CALENDAR, condition_value); + + } + else //not support yet + { + ERR("Invalid type(%s)", data_type); + return CAL_ERR_ARG_INVALID; + } + + count = cals_query_get_first_int_result(sql_value); + + return count; +} + +API int calendar_svc_get_all(int account_id, int calendar_id,const char *data_type, cal_iter **iter) +{ + CALS_FN_CALL; + int type; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN]; + + retv_if(NULL == data_type, CAL_ERR_ARG_NULL); + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + retvm_if(calendar_id < 0, CAL_ERR_ARG_INVALID, "calendar_id(%d) is Invalid", calendar_id); + + if(0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) + { + if (account_id == ALL_VISIBILITY_ACCOUNT || calendar_id==ALL_VISIBILITY_ACCOUNT) + { + sprintf(sql_value,"SELECT A.* FROM %s A, %s B ON A.calendar_id = B.rowid " + "WHERE type=%d AND B.visibility = 1 AND A.is_deleted = 0 " + "ORDER BY A.start_date_time", + CALS_TABLE_SCHEDULE, CALS_TABLE_CALENDAR, CAL_EVENT_SCHEDULE_TYPE); + } + else + { + if (calendar_id) + sprintf(sql_value,"SELECT * FROM %s " + "WHERE type=%d AND is_deleted = 0 AND calendar_id = %d " + "ORDER BY start_date_time", + CALS_TABLE_SCHEDULE, CAL_EVENT_SCHEDULE_TYPE, calendar_id); + else if (account_id) + sprintf(sql_value,"SELECT * FROM %s " + "WHERE type=%d AND is_deleted = 0 AND account_id = %d " + "ORDER BY start_date_time", + CALS_TABLE_SCHEDULE, CAL_EVENT_SCHEDULE_TYPE, account_id); + else + sprintf(sql_value,"SELECT * FROM %s " + "WHERE type=%d AND is_deleted = 0 " + "ORDER BY start_date_time", + CALS_TABLE_SCHEDULE, CAL_EVENT_SCHEDULE_TYPE); + } + + type = CAL_STRUCT_TYPE_SCHEDULE; + } + else if(0 == strcmp(data_type,CAL_STRUCT_TODO)) + { + if (calendar_id) + sprintf(sql_value,"SELECT * FROM %s WHERE type=%d AND is_deleted = 0 AND calendar_id = %d ", + CALS_TABLE_SCHEDULE, CAL_EVENT_TODO_TYPE, calendar_id); + else if (account_id) + sprintf(sql_value,"SELECT * FROM %s WHERE type=%d AND is_deleted = 0 AND account_id = %d ", + CALS_TABLE_SCHEDULE, CAL_EVENT_TODO_TYPE, account_id); + else + sprintf(sql_value,"SELECT * FROM %s WHERE type=%d AND is_deleted = 0 ", + CALS_TABLE_SCHEDULE, CAL_EVENT_TODO_TYPE); + + type = CAL_STRUCT_TYPE_TODO; + } + else if(0 == strcmp(data_type,CAL_STRUCT_CALENDAR)) + { + if (account_id) + sprintf(sql_value,"SELECT rowid,* FROM %s WHERE account_id = %d", CALS_TABLE_CALENDAR, account_id); + else + sprintf(sql_value,"SELECT rowid,* FROM %s", CALS_TABLE_CALENDAR); + + type = CAL_STRUCT_TYPE_CALENDAR; + } + else //not support yet + { + ERR("Unknown Type(%s)", data_type); + return CAL_ERR_ARG_INVALID; + } + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + + (*iter)->stmt = stmt; + (*iter)->i_type = type; + + return CAL_SUCCESS; +} + + +API int calendar_svc_get_list(int account_id, int calendar_id, + const char *data_type,const char *field_type, int offset,int count, cal_iter **iter) +{ + CALS_FN_CALL; + int type; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + + retv_if(NULL == data_type, CAL_ERR_ARG_NULL); + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + retvm_if(calendar_id < 0, CAL_ERR_ARG_INVALID, "calendar_id(%d) is Invalid", calendar_id); + + if(0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) + { + if(account_id == ALL_VISIBILITY_ACCOUNT || calendar_id==ALL_VISIBILITY_ACCOUNT) + { + sprintf(sql_value,"SELECT A.id, A.summary, A.location, A.all_day_event," + "A.start_date_time,A.end_date_time,A.repeat_item,A.week_start,A.week_flag,A.calendar_id " + "FROM %s A, %s B " + "WHERE A.type=%d AND B.visibility = 1 AND A.calendar_id = B.rowid AND A.is_deleted = 0 " + "ORDER BY A.start_date_time LIMIT %d, %d", + CALS_TABLE_SCHEDULE, CALS_TABLE_CALENDAR, CAL_EVENT_SCHEDULE_TYPE, offset, count); + } + else + { + char cond[CALS_SQL_MIN_LEN]; + cond[0] = '\0'; + + if (account_id) + sprintf(cond,"type=%d AND account_id = %d AND",CAL_EVENT_SCHEDULE_TYPE,account_id); + + if (calendar_id) + sprintf(cond,"type=%d AND calendar_id = %d AND",CAL_EVENT_SCHEDULE_TYPE,calendar_id); + + sprintf(sql_value,"SELECT id,summary,location,all_day_event," + "start_date_time,end_date_time,repeat_item,week_start,week_flag,calendar_id " + "FROM %s WHERE %s is_deleted = 0 ORDER BY start_date_time LIMIT %d,%d;", + CALS_TABLE_SCHEDULE, cond, offset, count); + } + + type = CAL_STRUCT_TYPE_SCHEDULE_LIST; + } + else if (0 == strcmp(data_type,CAL_STRUCT_TODO)) { + //cond_size = sprintf(condition_value,"WHERE A.type=%d AND",CAL_EVENT_TODO_TYPE); + ERR("data_type(%s) is not supported", data_type); + return CAL_ERR_ARG_INVALID; + } + else { + //cond_size = sprintf(condition_value,"WHERE "); + ERR("data_type(%s) is not supported", data_type); + return CAL_ERR_ARG_INVALID; + } + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + + (*iter)->stmt = stmt; + (*iter)->i_type = type; + + return CAL_SUCCESS; +} + + +API int calendar_svc_search_list(int account_id,int calendar_id,const char *data_type,const char *search_type,const void *search_value, + int offset,int count, cal_iter **iter) +{ + CALS_FN_CALL; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + int rc = 0; + char condition_value[1024] = {0}; + cal_value_type_t value_type = 0; + retex_if(NULL == data_type,,"Invalid parameter.\n"); + retex_if(NULL == iter,,"Invalid parameter.\n"); + retex_if(0 > calendar_id,,"Invalid parameter.\n"); + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + + value_type = __calendar_svc_get_type(CAL_STRUCT_TYPE_SCHEDULE,search_type); + + switch(value_type) + { + case VALUE_TYPE_TEXT: + + retex_if(search_value == NULL,,"search_value is NULL"); + + if(ALL_VISIBILITY_ACCOUNT == account_id) + { + sprintf(condition_value,"where st.type=%d and upper(%s) like upper('%%%s%%')",CAL_EVENT_SCHEDULE_TYPE, search_type, (char*)search_value); + } + else if(0 != account_id) + { + sprintf(condition_value,"where st.type=%d and upper(%s) like upper('%%%s%%') and account_id = %d",CAL_EVENT_SCHEDULE_TYPE, search_type, (char*)search_value, account_id); + } + else + { + sprintf(condition_value,"where st.type=%d and upper(%s) like upper('%%%s%%') ",CAL_EVENT_SCHEDULE_TYPE, search_type, (char*)search_value); + } + break; + case VALUE_TYPE_INT: + if(ALL_VISIBILITY_ACCOUNT == account_id) + { + sprintf(condition_value,"where st.type=%d and %s = %d ",CAL_EVENT_SCHEDULE_TYPE, search_type,(int)search_value); + } + else if(0 != account_id) + { + sprintf(condition_value,"where st.type=%d and %s = %d and account_id = %d",CAL_EVENT_SCHEDULE_TYPE, search_type, (int)search_value, account_id); + } + else + { + sprintf(condition_value,"where st.type=%d and %s = %d ",CAL_EVENT_SCHEDULE_TYPE, search_type, (int)search_value); + } + break; + + case VALUE_TYPE_TIME: + case VALUE_TYPE_DOUBLE: + case VALUE_TYPE_USER: + retex_if(true,,"Can not find"); + default: + break; + } + + if(0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) + { + if(account_id == ALL_VISIBILITY_ACCOUNT || calendar_id==ALL_VISIBILITY_ACCOUNT) + { + sprintf(sql_value,"select st.id,st.summary,st.location,st.all_day_event,st.start_date_time,st.end_date_time,st.repeat_item,st.week_start,st.week_flag,st.calendar_id " + "from schedule_table as st, calendar_table as ct %s " + "and ct.visibility = 1 and st.calendar_id = ct.rowid and " + "st.is_deleted = 0 order by st.summary limit %d,%d;",condition_value,offset,count); + } + else + { + + sprintf(sql_value,"select st.id,st.summary,st.location,st.all_day_event,st.start_date_time,st.end_date_time,st.repeat_item,st.week_start,st.week_flag,st.calendar_id "\ + "from schedule_table as st %s and is_deleted = 0 order by st.summary limit %d,%d;",condition_value,offset,count); + } + + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE_LIST; + } + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK,,"[ERROR]calendar_svc_get_all:Failed to get stmt!(sql:%s)\n",sql_value); + + (*iter)->stmt = stmt; + + + return CAL_SUCCESS; + +CATCH: + + if (iter && *iter != NULL) + { + CAL_FREE(*iter); + } + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return CAL_ERR_FAIL; +} + + +API int calendar_svc_update(cal_struct *record) +{ + CALS_FN_CALL; + int ret = 0; + + retv_if(NULL == record, CAL_ERR_ARG_NULL); + + cal_sch_full_t *event_record_schedule = NULL; + calendar_t *event_record_calendar = NULL; + cal_timezone_t *tz_info = NULL; + + ret = cals_begin_trans(); + retvm_if(CAL_SUCCESS != ret, ret, "cals_begin_trans() Failed(%d)", ret); + + switch(record->event_type) { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + event_record_schedule = record->user_data; + ret = cals_update_schedule(event_record_schedule->index,event_record_schedule); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_update_schedule() Failed(%d)", ret); + return ret; + } + break; + case CAL_STRUCT_TYPE_CALENDAR: + event_record_calendar = record->user_data; + ret = cals_update_calendar(event_record_calendar); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_update_calendar() Failed(%d)", ret); + return ret; + } + break; + case CAL_STRUCT_TYPE_TIMEZONE: + tz_info = record->user_data; + ret = cals_update_timezone(tz_info); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_update_timezone() Failed(%d)", ret); + return ret; + } + break; + default: + cals_end_trans(false); + ERR("Unknown event type(%d)", record->event_type); + return CAL_ERR_ARG_INVALID; + } + cals_end_trans(true); + + return CAL_SUCCESS; +} + + +API int calendar_svc_delete(const char *data_type, int index) +{ + CALS_FN_CALL; + int ret = 0; + + retv_if(NULL == data_type, CAL_ERR_ARG_NULL); + + ret = cals_begin_trans(); + retvm_if(CAL_SUCCESS != ret, ret, "cals_begin_trans() Failed(%d)", ret); + + if(0 == strcmp(data_type,CAL_STRUCT_SCHEDULE) || 0 == strcmp(data_type,CAL_STRUCT_TODO)) { + ret = cals_delete_schedule(index); + if (ret) { + cals_end_trans(false); + ERR("cals_delete_schedule() Failed(%d)", ret); + return ret; + } + } else if(0 == strcmp(data_type,CAL_STRUCT_CALENDAR)) { + if(DEFAULT_CALENDAR_ID == index) { + cals_end_trans(false); + return CAL_ERR_FAIL; + } + + ret = cals_delete_calendar(index); + if (ret) { + cals_end_trans(false); + ERR("cals_delete_calendar() Failed(%d)", ret); + return ret; + } + } else { + cals_end_trans(false); + ERR("Invalid data_type(%s)", data_type); + return CAL_ERR_ARG_INVALID; + } + cals_end_trans(true); + + return CAL_SUCCESS; +} + + +static inline int cals_remove_alarms_by_period(int calendar_id, time_t start_time, time_t end_time) +{ + int ret = 0; + char query[CALS_SQL_MIN_LEN]; + sqlite3_stmt *stmt = NULL; + + if (calendar_id) + sprintf(query, "SELECT id FROM %s WHERE start_date_time >= %ld AND start_date_time <= %ld AND calendar_id = %d", + CALS_TABLE_SCHEDULE, start_time, end_time, calendar_id); + else + sprintf(query, "SELECT id FROM %s WHERE start_date_time >= %ld AND start_date_time <= %ld", + CALS_TABLE_SCHEDULE, start_time, end_time); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + ret = cals_stmt_step(stmt); + if (ret < CAL_SUCCESS) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", ret); + return ret; + } + + while(CAL_TRUE == ret) + { + cals_alarm_remove(CALS_ALARM_REMOVE_BY_EVENT_ID, sqlite3_column_int(stmt,0)); + ret = cals_stmt_step(stmt); + } + sqlite3_finalize(stmt); + + return CAL_SUCCESS; +} + + +API int calendar_svc_event_delete_by_period(int calendar_id, time_t start_time, time_t end_time) +{ + CALS_FN_CALL; + char sql[CALS_SQL_MIN_LEN] = {0}; + int ret = 0; + + retvm_if(start_time < 0, CAL_ERR_ARG_INVALID, "start_time(%ld) Invalid", start_time); + retvm_if(end_time < 0, CAL_ERR_ARG_INVALID, "end_time(%ld) Invalid", end_time); + + ret = cals_begin_trans(); + retvm_if(CAL_SUCCESS != ret, ret, "cals_begin_trans() Failed(%d)", ret); + + ret = cals_remove_alarms_by_period(calendar_id, start_time, end_time); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_remove_alarms_by_period() Failed(%d)", ret); + return ret; + } + + time_t current_time = time(NULL); + + if (calendar_id) + sprintf(sql,"UPDATE %s SET is_deleted = 1,sync_status = %d,last_modified_time = %ld " + "WHERE start_date_time >= %ld AND start_date_time <= %ld AND calendar_id = %d", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED, current_time, start_time, end_time, calendar_id); + else + sprintf(sql,"UPDATE %s SET is_deleted = 1,sync_status = %d,last_modified_time = %ld " + "WHERE start_date_time >= %ld AND start_date_time <= %ld", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED, current_time, start_time, end_time); + + ret = cals_query_exec(sql); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_query_exec() Failed(%d)", ret); + return ret; + } + cals_end_trans(true); + + cals_notify(CALS_NOTI_TYPE_EVENT); + + return CAL_SUCCESS; +} + + +API int calendar_svc_delete_account (int account_id) +{ + CALS_FN_CALL; + int ret = 0; + char sql[512] = {0,}; + + retvm_if(account_id < 0, CAL_ERR_ARG_INVALID, "account_id(%d) is Invalid", account_id); + + ret = cals_alarm_remove(CALS_ALARM_REMOVE_BY_ACC_ID, account_id); + retvm_if(CAL_SUCCESS != ret, ret, "cals_alarm_remove() Failed(%d)", ret); + + //delete schedule + if (account_id) + sprintf(sql,"DELETE FROM %s WHERE account_id = %d", CALS_TABLE_SCHEDULE, account_id); + else + sprintf(sql,"DELETE FROM %s", CALS_TABLE_SCHEDULE); + + ret = cals_query_exec(sql); + retvm_if(ret, ret, "cals_query_exec() Failed(%d)", ret); + + calendar_svc_delete_all(account_id, CAL_STRUCT_CALENDAR); + + return CAL_SUCCESS; +} + + +API int calendar_svc_clean_after_sync(int account_id) +{ + CALS_FN_CALL; + int ret = 0; + char sql[256] = {0}; + + retvm_if(account_id < 0, CAL_ERR_ARG_INVALID, "account_id(%d) is Invalid", account_id); + + if(account_id) + sprintf(sql,"delete from %s where (is_deleted = 1 and account_id = %d);", + CALS_TABLE_SCHEDULE, account_id); + else + sprintf(sql,"delete from %s where is_deleted = 1;", CALS_TABLE_SCHEDULE); + + ret = cals_query_exec(sql); + retvm_if(ret, ret, "cals_query_exec() Failed(%d)", ret); + + return CAL_SUCCESS; +} + + +API int calendar_svc_delete_all(int account_id, const char *data_type) +{ + int ret = 0; + + retvm_if(account_id < 0, CAL_ERR_ARG_INVALID, "account_id(%d) is Invalid", account_id); + + if(data_type == NULL) //delete all data from db by account id + { + ret = __cal_service_delete_all_records(account_id, CAL_EVENT_NONE); + retvm_if(CAL_SUCCESS != ret, ret, "__cal_service_delete_all_records() Failed(%d)", ret); + ret = cals_delete_calendars(account_id); + retvm_if(CAL_SUCCESS != ret, ret, "cals_delete_calendars() Failed(%d)", ret); + } + else if(0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) + { + ret = __cal_service_delete_all_records(account_id, CAL_EVENT_SCHEDULE_TYPE); + retvm_if(CAL_SUCCESS != ret, ret, "__cal_service_delete_all_records() Failed(%d)", ret); + } + else if(0 == strcmp(data_type,CAL_STRUCT_TODO)) + { + ret = __cal_service_delete_all_records(account_id, CAL_EVENT_TODO_TYPE); + retvm_if(CAL_SUCCESS != ret, ret, "__cal_service_delete_all_records() Failed(%d)", ret); + } + else if(0 == strcmp(data_type,CAL_STRUCT_CALENDAR)) + { + ret = cals_delete_calendars(account_id); + retvm_if(CAL_SUCCESS != ret, ret, "cals_delete_calendars() Failed(%d)", ret); + } + else + { + ERR("Unknow data_type(%s)", data_type); + return CAL_ERR_ARG_INVALID; + } + + return CAL_SUCCESS; +} + + +API int calendar_svc_find_event_list(int account_id,const char *search_type,const void *search_value, cal_iter **iter) +{ + CALS_FN_CALL; + int ret = 0; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + cal_value_type_t value_type = 0; + + retv_if(NULL == search_type, CAL_ERR_ARG_NULL); + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + + value_type = __calendar_svc_get_type(CAL_STRUCT_TYPE_SCHEDULE,search_type); + + switch(value_type) + { + case VALUE_TYPE_TEXT: + retv_if(NULL == search_value, CAL_ERR_ARG_NULL); + + if(ALL_VISIBILITY_ACCOUNT == account_id) + { + sprintf(sql_value,"SELECT * FROM %s WHERE %s like upper('%%%s%%') AND is_deleted = 0;", + CALS_TABLE_SCHEDULE, search_type, (char*)search_value); + } + else if(0 != account_id) + { + sprintf(sql_value,"SELECT * FROM %s WHERE %s like upper('%%%s%%') AND is_deleted = 0 and account_id = %d;", + CALS_TABLE_SCHEDULE, search_type, (char*)search_value, account_id); + } + else + { + sprintf(sql_value,"SELECT * FROM %s WHERE %s like upper('%%%s%%') AND is_deleted = 0;", + CALS_TABLE_SCHEDULE, search_type, (char*)search_value); + } + break; + case VALUE_TYPE_INT: + if(ALL_VISIBILITY_ACCOUNT == account_id) + { + sprintf(sql_value,"SELECT * FROM %s WHERE %s = %d AND is_deleted = 0;", + CALS_TABLE_SCHEDULE, search_type,(int)search_value); + } + else if(0 != account_id) + { + sprintf(sql_value,"SELECT * FROM %s WHERE %s = %d AND is_deleted = 0 AND account_id = %d;", + CALS_TABLE_SCHEDULE, search_type, (int)search_value, account_id); + } + else + { + sprintf(sql_value,"SELECT * FROM %s WHERE %s = %d AND is_deleted = 0;", + CALS_TABLE_SCHEDULE, search_type, (int)search_value); + } + break; + case VALUE_TYPE_USER: + if (0 == strcmp(CAL_VALUE_INT_ALARMS_ID, search_type)) { + ret = cals_alarm_get_event_id((int)search_value); + sprintf(sql_value,"SELECT * FROM %s WHERE id = %d AND is_deleted = 0", + CALS_TABLE_SCHEDULE, ret); + break; + } + case VALUE_TYPE_TIME: + case VALUE_TYPE_DOUBLE: + default: + ERR("Unknown Type(%s:%d)", search_type, value_type); + break; + } + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + if(NULL == *iter) + { + *iter = calloc(1, sizeof(cal_iter)); + if (NULL == *iter) { + sqlite3_finalize(stmt); + ERR("calloc() Failed(%d)", errno); + return CAL_ERR_OUT_OF_MEMORY; + } + } + + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE; + + return CAL_SUCCESS; +} + + +API int calendar_svc_find_recurring_event_list(int account_id, cal_iter **iter) +{ + CALS_FN_CALL; + sqlite3_stmt *stmt = NULL; + char sql_value[512] = {0}; + + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + + if(0 != account_id) + snprintf(sql_value, sizeof(sql_value), "select * from %s where repeat_item > 0 and is_deleted = 0 and account_id = %d", + CALS_TABLE_SCHEDULE, account_id); + else + snprintf(sql_value, sizeof(sql_value), "select * from %s where repeat_item > 0 and is_deleted = 0;", + CALS_TABLE_SCHEDULE); + + stmt = cals_query_prepare(sql_value); + if (NULL == stmt) { + ERR("cals_query_prepare() Failed"); + free(*iter); + return CAL_ERR_DB_FAILED; + } + + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE; + + return CAL_SUCCESS; +} + + +API int calendar_svc_find_event_list_by_filter(int account_id, int filter_count, const char *search_type[], const void *search_value[], cal_iter **iter) +{ + CALS_FN_CALL; + + int i, j, cond_len = 0; + int rc = 0; + sqlite3_stmt *stmt = NULL; + char sql_value[2560] = {0}; + char sql_condition_value[2048] = {0}; + char sql_temp[256] = {0}; + cal_value_type_t value_type = 0; + bool category_table_used = false; + + retex_if(0 >= filter_count,,"Invalid parameter(filter_count).\n"); + retex_if(NULL == iter,,"Invalid parameter(iter).\n"); + + if(*iter == NULL) + { + *iter = malloc(sizeof(cal_iter)); + retex_if(NULL == *iter,,"Failed to malloc!\n"); + } + memset(*iter,0x00,sizeof(cal_iter)); + + for (i=0; i j) + len += snprintf(sql_temp+len, sizeof(sql_temp)-len, "or "); + } + len += snprintf(sql_temp+len, sizeof(sql_temp)-len, ") and "); + if(sizeof(sql_temp) <= len) { + ERR("condition is too long"); + free(*iter); + return CAL_ERR_ARG_INVALID; + } + } + else + { + snprintf(sql_temp, sizeof(sql_temp), "%s = %d and", search_type[i], (int)search_value[i]); + } + break; + case VALUE_TYPE_TIME: + // Doesn't consider the recurrence. + if(!strncmp(CAL_VALUE_GMT_START_DATE_TIME, search_type[i], 128)) // start time min value + { + snprintf(sql_temp, sizeof(sql_temp), "%s >= %d and ", search_type[i], (int)search_value[i]); + } + if(!strncmp(CAL_VALUE_GMT_END_DATE_TIME, search_type[i], 128)) // start time max value + { + snprintf(sql_temp, sizeof(sql_temp), "%s <= %d and ", CAL_VALUE_GMT_START_DATE_TIME, (int)search_value[i]); + } + break; + case VALUE_TYPE_DOUBLE: + case VALUE_TYPE_USER: + retex_if(true,,"Can not find!\n"); + default: + break; + } + + cond_len += snprintf(sql_condition_value+cond_len, sizeof(sql_condition_value)-cond_len, "%s", sql_temp); + if(sizeof(sql_condition_value) <= cond_len) { + ERR("condition is too long"); + free(*iter); + return CAL_ERR_ARG_INVALID; + } + } + if(0 != account_id) + { + if(false==category_table_used) + snprintf(sql_value, sizeof(sql_value), "select schedule_table.* from schedule_table where %s is_deleted = 0 and account_id = %d;", sql_condition_value, account_id); + else + snprintf(sql_value, sizeof(sql_value), "select schedule_table.* from schedule_table, cal_meeting_category_table where %s is_deleted = 0 and account_id = %d;", sql_condition_value, account_id); + } + else + { + if(false==category_table_used) + snprintf(sql_value, sizeof(sql_value), "select schedule_table.* from schedule_table where %s is_deleted = 0;", sql_condition_value); + else + snprintf(sql_value, sizeof(sql_value), "select schedule_table.* from schedule_table, cal_meeting_category_table where %s is_deleted = 0;", sql_condition_value); + } + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK,,"[ERROR]calendar_svc_find_event_list_by_filter: Failed to get stmt!(%s)\n", sql_value); + + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE; + return CAL_SUCCESS; +CATCH: + if (iter && *iter != NULL) + { + CAL_FREE(*iter); + } + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + return CAL_ERR_FAIL; +} + + +static inline int __calendar_svc_find_calendar_list(int account_id,int calendar_id,const char *search_type,const void *search_value, cal_iter **iter) +{ + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + int rc = 0; + cal_value_type_t value_type = 0; + + //retex_if(0 < account_id,,"[ERROR]calendar_svc_find_event_list:Invalid parameter(account_id)"); + retex_if(NULL == search_type ,," [ERROR]calendar_svc_find_event_list:Invalid parameter(search_type).\n"); + retex_if(NULL == iter,," [ERROR]calendar_svc_find_event_list:Invalid parameter(iter).\n"); + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + + value_type = __calendar_svc_get_type(CAL_STRUCT_TYPE_CALENDAR,search_type); + + switch(value_type) + { + case VALUE_TYPE_TEXT: + if(account_id) + sprintf(sql_value,"select rowid,* from calendar_table where %s like '%%%s%%' and is_deleted = 0 and account_id = %d;", search_type, (char*)search_value, account_id); + else + sprintf(sql_value,"select rowid,* from calendar_table where %s like '%%%s%%' and is_deleted = 0;", search_type, (char*)search_value); + break; + case VALUE_TYPE_INT: + if(account_id) + sprintf(sql_value,"select rowid,* from calendar_table where %s = %d and is_deleted = 0 and account_id = %d;", search_type, (int)search_value, account_id); + else + sprintf(sql_value,"select rowid,* from calendar_table where %s = %d and is_deleted = 0;", search_type, (int)search_value); + break; + case VALUE_TYPE_TIME: + case VALUE_TYPE_DOUBLE: + case VALUE_TYPE_USER: + default: + retex_if(true,,"Can not find!\n"); + } + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK,,"[ERROR]calendar_svc_find_event_list:Failed to get stmt!(%s)\n",sql_value); + + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE; + + return CAL_SUCCESS; + +CATCH: + + if (iter && *iter != NULL) + { + CAL_FREE(*iter); + } + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + + return CAL_ERR_FAIL; + +} + + +static inline int __calendar_svc_find_timezone_list(int account_id,int calendar_id,const char *search_type,const void *search_value, cal_iter **iter) +{ + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + int rc = 0; + cal_value_type_t value_type = 0; + + //retex_if(0 < account_id,,"[ERROR]calendar_svc_find_event_list:Invalid parameter(account_id)"); + retex_if(NULL == search_type ,,"Invalid parameter(search_type)"); + retex_if(NULL == iter,,"Invalid parameter(iter)"); + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + + value_type = __calendar_svc_get_type(CAL_STRUCT_TYPE_TIMEZONE,search_type); + + switch(value_type) + { + case VALUE_TYPE_TEXT: + if(0 != account_id) + sprintf(sql_value,"select rowid,* from timezone_table where %s like '%%%s%%' and account_id = %d;", search_type, (char*)search_value, account_id); + else + sprintf(sql_value,"select rowid,* from timezone_table where %s like '%%%s%%' ;", search_type, (char*)search_value); + + break; + case VALUE_TYPE_INT: + if(0 != account_id) + sprintf(sql_value,"select rowid,* from timezone_table where %s = %d and account_id = %d;", search_type, (int)search_value, account_id); + else + sprintf(sql_value,"select rowid,* from timezone_table where %s = %d ;", search_type, (int)search_value); + break; + case VALUE_TYPE_TIME: + case VALUE_TYPE_DOUBLE: + case VALUE_TYPE_USER: + default: + retex_if(true,,"Can not find!\n"); + } + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK,,"ailed to get stmt!(%s)",sql_value); + + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_TIMEZONE; + + return CAL_SUCCESS; + +CATCH: + + if (iter && *iter != NULL) + { + CAL_FREE(*iter); + } + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + + return CAL_ERR_FAIL; + +} + + +API int calendar_svc_find(int account_id,int calendar_id,const char *data_type,const char *search_type,const void *search_value, cal_iter **iter) +{ + retv_if(NULL == data_type, CAL_ERR_ARG_NULL); + + if(0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) + { + calendar_svc_find_event_list(account_id,search_type,search_value,iter); + } + else if(0 == strcmp(data_type,CAL_STRUCT_CALENDAR)) + { + __calendar_svc_find_calendar_list(account_id, calendar_id, search_type, search_value, iter); + } + else if(0 == strcmp(data_type,CAL_STRUCT_TIMEZONE)) + { + __calendar_svc_find_timezone_list(account_id, calendar_id, search_type, search_value, iter); + } + else { + ERR("Unknown Type(%s)", data_type); + return CAL_ERR_FAIL; + } + + return CAL_SUCCESS; +} + + +API int calendar_svc_get_updated_event_list(int account_id, time_t timestamp, cal_iter **iter) +{ + CALS_FN_CALL; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + + cal_iter *iter_value = NULL; + + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + retvm_if(timestamp < 0, CAL_ERR_ARG_INVALID, "timestamp(%ld) is Invalid", timestamp); + + iter_value = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == iter_value, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed"); + + if (account_id) + sprintf(sql_value,"SELECT * FROM %s WHERE last_modified_time > %ld AND account_id = %d", + CALS_TABLE_SCHEDULE, timestamp, account_id); + else + sprintf(sql_value,"SELECT * FROM %s WHERE last_modified_time > %ld", + CALS_TABLE_SCHEDULE, timestamp); + + stmt = cals_query_prepare(sql_value); + if (NULL == stmt) { + ERR("cals_query_prepare() Failed"); + free(iter_value); + return CAL_ERR_DB_FAILED; + } + + iter_value->stmt = stmt; + iter_value->i_type = CAL_STRUCT_TYPE_SCHEDULE; + *iter = iter_value; + + return CAL_SUCCESS; +} + + + +API int calendar_svc_get_month_event_list_by_period(int account_id, + time_t startdate, time_t enddate, cal_iter **iter) +{ + CALS_FN_CALL; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + time_t gm_startdate = 0; + time_t gm_enddate =0; + + //retex_if(0 > account_id,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(account_id)!\n"); + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + retv_if(startdate < 0, CAL_ERR_ARG_INVALID); + retv_if(enddate < 0, CAL_ERR_ARG_INVALID); + + //switch((*iter)->i_type) + //{ + // case CAL_STRUCT_TYPE_SCHEDULE: + //calendar_svc_util_local_to_gmt(startdate,&gm_startdate); + //calendar_svc_util_local_to_gmt(enddate,&gm_enddate); + gm_startdate = startdate - SECSPERDAY; + gm_enddate = enddate + SECSPERDAY; + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY,"calloc() Failed(%d)", errno); + + (*iter)->is_patched = FALSE; + + if(account_id == ALL_VISIBILITY_ACCOUNT) { + sprintf(sql_value,"select schedule_table.* from schedule_table,calendar_table "\ + "where schedule_table.type=%d and schedule_table.is_deleted = 0 "\ + "and schedule_table.calendar_id = calendar_table.rowid and calendar_table.visibility = 1 "\ + "and ((schedule_table.repeat_item = 0 and schedule_table.start_date_time <= %d and schedule_table.end_date_time >=%d) "\ + "or (schedule_table.repeat_item<>0 and schedule_table.repeat_end_date>=%d)) limit 10;" + ,CAL_EVENT_SCHEDULE_TYPE, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } else { + if(0 != account_id) { + sprintf(sql_value,"select * from schedule_table where type=%d and is_deleted = 0 and account_id = %d and\ + ((repeat_item = 0 and start_date_time <= %d and end_date_time >=%d) \ + or (repeat_item<>0 and repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE,account_id, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } else { + sprintf(sql_value,"select * from schedule_table where type=%d and is_deleted = 0 and\ + ((repeat_item = 0 and start_date_time <= %d and end_date_time >=%d) \ + or (repeat_item<>0 and repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } + } + stmt = cals_query_prepare(sql_value); + if (NULL == stmt) { + ERR("cals_query_prepare() Failed"); + free(*iter); + return CAL_ERR_DB_FAILED; + } + + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE; + + return CAL_SUCCESS; +} + + +API int calendar_svc_get_event_list_by_period (int account_id, time_t startdate, time_t enddate, cal_iter **iter) +{ + CALS_FN_CALL; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + int rc = 0; + time_t gm_startdate = 0; + time_t gm_enddate =0; + + //retex_if(0 > account_id,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(account_id)!\n"); + retex_if(NULL == iter,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(iter)!\n"); + retex_if(startdate < 0,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(startdate)!\n"); + retex_if(enddate < 0,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(enddate)!\n"); + + //switch((*iter)->i_type) + //{ + // case CAL_STRUCT_TYPE_SCHEDULE: + gm_startdate = startdate - SECSPERDAY; + gm_enddate = enddate + SECSPERDAY; + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + + (*iter)->is_patched = FALSE; + + if(account_id == ALL_VISIBILITY_ACCOUNT) + { + sprintf(sql_value,"select schedule_table.* from schedule_table,calendar_table "\ + "where schedule_table.type=%d and schedule_table.is_deleted = 0 "\ + "and schedule_table.calendar_id = calendar_table.rowid and calendar_table.visibility = 1 "\ + "and ((schedule_table.repeat_item = 0 and schedule_table.start_date_time <= %d and schedule_table.end_date_time >=%d) "\ + "or (schedule_table.repeat_item<>0 and schedule_table.repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } + else + { + + if(0 != account_id) + { + sprintf(sql_value,"select * from schedule_table where type=%d and is_deleted = 0 and account_id = %d and\ + ((repeat_item = 0 and start_date_time <= %d and end_date_time >=%d) \ + or (repeat_item<>0 and repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE,account_id, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } + else + { + sprintf(sql_value,"select * from schedule_table where type=%d and is_deleted = 0 and\ + ((repeat_item = 0 and start_date_time <= %d and end_date_time >=%d) \ + or (repeat_item<>0 and repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } + + } + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK,printf("errmsg is %s\n",sqlite3_errmsg(calendar_db_handle)),"[ERROR]calendar_svc_get_event_list_by_period:Failed to get stmt!\n"); + + + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE; + + return CAL_SUCCESS; + +CATCH: + + if (iter) + { + CAL_FREE(*iter); + } + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return CAL_ERR_FAIL; +} + + + +API int calendar_svc_get_event_list_by_tm_period (int account_id,int calendar_id, struct tm* startdate, struct tm* enddate, cal_iter **iter) +{ + CALS_FN_CALL; + sqlite3_stmt *stmt = NULL; + char sql_value[CALS_SQL_MIN_LEN] = {0}; + int rc = 0; + + time_t gm_startdate = 0; + time_t gm_enddate =0; + time_t local_startdate = 0; + time_t local_enddate =0; + //retex_if(0 > account_id,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(account_id)!\n"); + retex_if(NULL == iter,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(iter)!\n"); + retex_if(startdate < 0,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(startdate)!\n"); + retex_if(enddate < 0,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(enddate)!\n"); + + //switch((*iter)->i_type) + //{ + // case CAL_STRUCT_TYPE_SCHEDULE: + local_startdate = cals_mktime(startdate); + local_enddate = cals_mktime(enddate); + + calendar_svc_util_local_to_gmt(local_startdate,&gm_startdate); + calendar_svc_util_local_to_gmt(local_enddate,&gm_enddate); + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + (*iter)->is_patched = FALSE; + + if(account_id == ALL_VISIBILITY_ACCOUNT) + { + sprintf(sql_value,"select schedule_table.* from schedule_table,calendar_table "\ + "where schedule_table.type=%d and schedule_table.is_deleted = 0 "\ + "and schedule_table.calendar_id = calendar_table.rowid and calendar_table.visibility = 1 "\ + "and ((schedule_table.repeat_item = 0 and schedule_table.start_date_time <= %d and schedule_table.end_date_time >=%d) "\ + "or (schedule_table.repeat_item<>0 and schedule_table.repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE,(int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + + DBG("%s",sql_value); + } + else + { + + if(0 != calendar_id) + { + sprintf(sql_value,"select * from schedule_table where type=%d and is_deleted = 0 and calendar_id = %d and\ + ((repeat_item = 0 and start_date_time <= %d and end_date_time >=%d) \ + or (repeat_item<>0 and repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE,calendar_id, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } + else if(0 != account_id) + { + sprintf(sql_value,"select * from schedule_table where type=%d and is_deleted = 0 and account_id = %d and\ + ((repeat_item = 0 and start_date_time <= %d and end_date_time >=%d) \ + or (repeat_item<>0 and repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE,account_id, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } + else + { + sprintf(sql_value,"select * from schedule_table where type=%d and is_deleted = 0 and\ + ((repeat_item = 0 and start_date_time <= %d and end_date_time >=%d) \ + or (repeat_item<>0 and repeat_end_date>=%d));" + ,CAL_EVENT_SCHEDULE_TYPE, (int)gm_enddate,(int)gm_startdate, (int)gm_startdate); + } + } + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK,,"[ERROR]calendar_svc_get_event_list_by_period:Failed to get stmt!\n"); + + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE; + + return CAL_SUCCESS; + +CATCH: + + if (iter) + { + CAL_FREE(*iter); + } + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return CAL_ERR_FAIL; +} + + +API int calendar_svc_convert_id_to_uid(const char *data_type,int index,char **uid) +{ + int rc = -1; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + sqlite3_stmt *stmt = NULL; + int return_value = CAL_SUCCESS; + + retex_if(uid == NULL,return_value = CAL_ERR_ARG_NULL, "The calendar database hasn't been opened."); + + retex_if(NULL == calendar_db_handle, return_value = CAL_ERR_DB_NOT_OPENED, "The calendar database hasn't been opened."); + + //sprintf(sql_value, "select * from cal_participant_table where event_id = %d;", panticipant_index); + // TODO: make query!!!! + if((0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) || (0 == strcmp(data_type,CAL_STRUCT_TODO))) + { + sprintf(sql_value,"select uid from schedule_table where id=%d;",index); + } + else if(0 == strcmp(data_type,CAL_STRUCT_CALENDAR)) + { + sprintf(sql_value,"select uid from calendar_table where rowid=%d;",index); + } + + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK, return_value = CAL_ERR_DB_FAILED, "Failed to get stmt!!"); + + rc = sqlite3_step(stmt); + retex_if(rc!= SQLITE_ROW && rc!= SQLITE_OK && rc!= SQLITE_DONE, return_value = CAL_ERR_DB_FAILED, "[ERROR]cal_db_service_get_participant_info_by_index:Query error !!"); + + cal_db_get_text_from_stmt(stmt,uid,0); + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return CAL_SUCCESS; + +CATCH: + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return return_value; +} + +int calendar_svc_convert_uid_to_id(const char *data_type,char *uid,int *index) +{ + int rc = -1; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + sqlite3_stmt *stmt = NULL; + int return_value = CAL_SUCCESS; + + retex_if(uid == NULL, return_value = CAL_ERR_ARG_NULL, "The calendar database hasn't been opened."); + + retex_if(NULL == calendar_db_handle, return_value = CAL_ERR_DB_NOT_OPENED, "The calendar database hasn't been opened."); + + //sprintf(sql_value, "select * from cal_participant_table where event_id = %d;", panticipant_index); + // TODO: make query!!!! + if((0 == strcmp(data_type,CAL_STRUCT_SCHEDULE)) || (0 == strcmp(data_type,CAL_STRUCT_TODO))) + { + sprintf(sql_value,"select id from schedule_table where uid=%s;",uid); + } + else if(0 == strcmp(data_type,CAL_STRUCT_CALENDAR)) + { + sprintf(sql_value,"select rowid from calendar_table where uid=%s;",uid); + } + + + rc = sqlite3_prepare_v2(calendar_db_handle, sql_value, strlen(sql_value), &stmt, NULL); + retex_if(rc != SQLITE_OK, return_value = CAL_ERR_DB_FAILED, "Failed to get stmt!!"); + + rc = sqlite3_step(stmt); + retex_if(rc!= SQLITE_ROW && rc!= SQLITE_OK && rc!= SQLITE_DONE, return_value = CAL_ERR_DB_FAILED, "[ERROR]cal_db_service_get_participant_info_by_index:Query error !!"); + + *index = sqlite3_column_int(stmt,0); + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return CAL_SUCCESS; + +CATCH: + + if (stmt != NULL) + { + sqlite3_finalize(stmt); + stmt = NULL; + } + + return return_value; +} + + +API int calendar_svc_iter_get_info(cal_iter *iter, cal_struct **row_event) +{ + cal_sch_full_t *sch_record = NULL; + calendar_t *cal_record = NULL; + cal_timezone_t *tz_record = NULL; + + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + retv_if(NULL == iter->stmt, CAL_ERR_ARG_INVALID); + retv_if(NULL == row_event, CAL_ERR_ARG_NULL); + + if(iter->is_patched!=TRUE) + { + int ret = calendar_svc_iter_next(iter); + if(ret == CAL_ERR_FINISH_ITER) + return CAL_ERR_NO_DATA; + else if(ret != CAL_SUCCESS) + return ret; + } + + int error_code = 0; + + switch(iter->i_type) + { + case CAL_STRUCT_TYPE_SCHEDULE_LIST: + if (NULL == *row_event) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_SCHEDULE); + retvm_if(NULL == *row_event, CAL_ERR_FAIL, "calendar_svc_struct_new(SCHEDULE) Failed"); + } + sch_record = (*row_event)->user_data; + retvm_if(NULL == sch_record, CAL_ERR_FAIL, "row_event is Invalid"); + + cal_db_service_convert_stmt_to_list_field_record(iter->stmt,sch_record,true); + break; + case CAL_STRUCT_TYPE_SCHEDULE: + if (NULL == *row_event) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_SCHEDULE); + retvm_if(NULL == *row_event, CAL_ERR_FAIL, "calendar_svc_struct_new(SCHEDULE) Failed"); + } + sch_record = (cal_sch_full_t*)(*row_event)->user_data; + retvm_if(NULL == sch_record, CAL_ERR_FAIL, "row_event is Invalid"); + + cals_stmt_get_full_schedule(iter->stmt,sch_record,true); + + cal_db_service_get_participant_info_by_index(sch_record->index,&(sch_record->attendee_list),&error_code); + cal_db_service_get_meeting_category_info_by_index(sch_record->index,&(sch_record->meeting_category),&error_code); + cal_db_service_get_recurrency_exception(sch_record->index,&(sch_record->exception_date_list),&error_code); + cals_get_alarm_info(sch_record->index, &(sch_record->alarm_list)); + + break; + case CAL_STRUCT_TYPE_TODO: + if (NULL == *row_event) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_TODO); + retvm_if(NULL == *row_event, CAL_ERR_FAIL, "calendar_svc_struct_new(TODO) Failed"); + } + sch_record = (cal_sch_full_t*)(*row_event)->user_data; + retvm_if(NULL == sch_record, CAL_ERR_FAIL, "row_event is Invalid"); + + cals_stmt_get_full_schedule(iter->stmt,sch_record,true); + + break; + + case CAL_STRUCT_TYPE_CALENDAR: + if (NULL == *row_event) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_CALENDAR); + retvm_if(NULL == *row_event, CAL_ERR_FAIL, "calendar_svc_struct_new(CALENDAR) Failed"); + } + cal_record = (calendar_t*)(*row_event)->user_data; + retvm_if(NULL == cal_record, CAL_ERR_FAIL, "row_event is Invalid"); + + cals_stmt_get_calendar(iter->stmt,cal_record); + + break; + case CAL_STRUCT_TYPE_TIMEZONE: + if (NULL == *row_event) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_TIMEZONE); + retvm_if(NULL == *row_event, CAL_ERR_FAIL, "calendar_svc_struct_new(TIMEZONE) Failed"); + } + tz_record = (cal_timezone_t*)(*row_event)->user_data; + retvm_if(NULL == tz_record, CAL_ERR_FAIL, "row_event is Invalid"); + + cal_db_service_convert_stmt_to_tz_info(iter->stmt,tz_record); + break; + default: + break; + } + + return CAL_SUCCESS; +} + + +API int calendar_svc_iter_next(cal_iter *iter) +{ + int ret = 0; + + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + + if (iter->is_patched == FALSE) + iter->is_patched = TRUE; + + ret = cals_stmt_step(iter->stmt); + retvm_if(ret < CAL_SUCCESS, ret, "cals_stmt_step() Failed(%d)", ret); + + if (CAL_SUCCESS == ret) + return CAL_ERR_FINISH_ITER; + + return CAL_SUCCESS; +} + +API int calendar_svc_iter_remove(cal_iter **iter) +{ + CALS_FN_CALL; + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + retv_if(NULL == *iter, CAL_ERR_ARG_NULL); + + if ((*iter)->stmt) + { + sqlite3_finalize((*iter)->stmt); + (*iter)->stmt = NULL; + } + + free(*iter); + *iter = NULL; + + return CAL_SUCCESS; +} + + +API int calendar_svc_util_next_valid_event(cal_struct *event, time_t start_time, + time_t end_time, time_t *next_valid_start_time, time_t *next_valid_end_time) +{ + CALS_FN_CALL; + int ret = 0; + cal_sch_full_t *temp_sch_full; + static cal_date_param_t cal_date_param; + struct tm start_tm, end_tm; + struct tm event_start_tm = {0}; + struct tm event_end_tm = {0}; + + retv_if(NULL == event, CAL_ERR_ARG_NULL); + retv_if(NULL == event->user_data, CAL_ERR_ARG_INVALID); + retv_if(NULL == next_valid_start_time, CAL_ERR_ARG_NULL); + retv_if(NULL == next_valid_end_time, CAL_ERR_ARG_NULL); + + retvm_if(start_time < 0, CAL_ERR_ARG_INVALID, "start_time(%ld) is Invalid", start_time); + retvm_if(end_time < 0, CAL_ERR_ARG_INVALID, "end_time(%ld) is Invalid", end_time); + + temp_sch_full = event->user_data; + + memcpy(&event_start_tm,cals_tmtime(&start_time),sizeof(struct tm)); + memcpy(&event_end_tm,cals_tmtime(&end_time),sizeof(struct tm)); + + if((*next_valid_start_time == 0) && (*next_valid_end_time == 0)) + { + cal_service_set_date_param(&cal_date_param, temp_sch_full); + } + + ret = cal_db_service_get_next_valid_exception_time(temp_sch_full, + &cal_date_param,cal_date_param.exception_date_list,&event_start_tm,&event_end_tm,&start_tm,&end_tm); + retvm_if(ret, ret, "cal_db_service_get_next_valid_exception_time() Failed(%d)", ret); + + *next_valid_start_time = mktime(&start_tm); + *next_valid_end_time = mktime(&end_tm); + + //ERR("%d-start_tm(%d/%d/%d %d)",temp_sch_full->index, start_tm.tm_year+1900,start_tm.tm_mon+1,start_tm.tm_mday,start_tm.tm_hour); + //ERR("%d-end_tm(%d/%d/%d %d)",temp_sch_full->index,end_tm.tm_year+1900,end_tm.tm_mon+1,end_tm.tm_mday,end_tm.tm_hour); + + return CAL_SUCCESS; +} + + +API int calendar_svc_util_next_valid_event_tm(cal_struct *event, struct tm *start_tm, + struct tm *end_tm, struct tm *next_valid_start_tm, struct tm *next_valid_end_tm) +{ + int ret = 0; + cal_sch_full_t *temp_sch_full; + static cal_date_param_t cal_date_param; + + retv_if(NULL == event, CAL_ERR_ARG_NULL); + retv_if(NULL == event->user_data, CAL_ERR_ARG_INVALID); + retv_if(NULL == next_valid_start_tm, CAL_ERR_ARG_NULL); + retv_if(NULL == next_valid_end_tm, CAL_ERR_ARG_NULL); + retv_if(NULL == start_tm, CAL_ERR_ARG_NULL); + retv_if(NULL == end_tm, CAL_ERR_ARG_NULL); + + temp_sch_full = (cal_sch_full_t *)event->user_data; + + if((next_valid_start_tm->tm_year == 0) && (next_valid_end_tm->tm_year == 0)) + { + cal_service_set_date_param(&cal_date_param, temp_sch_full); + } + + ret = cal_db_service_get_next_valid_exception_time(temp_sch_full, + &cal_date_param,cal_date_param.exception_date_list,start_tm,end_tm,next_valid_start_tm,next_valid_end_tm); + retvm_if(ret, ret, "cal_db_service_get_next_valid_exception_time() Failed(%d)", ret); + + CALS_DBG("%d-start_tm(%d/%d/%d %d)",temp_sch_full->index, next_valid_start_tm->tm_year+1900,next_valid_start_tm->tm_mon+1,next_valid_start_tm->tm_mday,next_valid_start_tm->tm_hour); + CALS_DBG("%d-end_tm(%d/%d/%d %d)",temp_sch_full->index,next_valid_end_tm->tm_year+1900,next_valid_end_tm->tm_mon+1,next_valid_end_tm->tm_mday,next_valid_end_tm->tm_hour); + + return CAL_SUCCESS; +} + + +time_t calendar_svc_util_mk_localtime(struct tm* tmTime) +{ + retvm_if(NULL == tmTime,0,"Invalid parameter(tmTime)!\n"); + + if(cal_svc_tm_value.is_initialize == false){ + cal_svc_set_tz_base_info(tmTime->tm_year); //local time + } + + return cals_mktime(tmTime)-cal_svc_tm_value.localtime_offset; +} + +API int calendar_svc_util_gmt_to_local (time_t fromTime, time_t *toTime) +{ + retex_if(toTime==NULL,,"[ERROR]calendar_svc_util_gmt_to_local:Invalid parameter(toTime)!\n"); + struct tm * cur_time = NULL; + struct tm ttm; + cur_time = gmtime_r(&fromTime,&ttm); + + retex_if(cur_time==NULL,,"[ERROR]calendar_svc_util_gmt_to_local:Invalid parameter(fromTime)!\n"); + + if( (cal_svc_tm_value.is_initialize == false) || + ((cal_svc_tm_value.local_dst_offset !=0) && + (cal_svc_tm_value.start_local_dst_date_time.tm_year != cur_time->tm_year)) ){ + cal_svc_set_tz_base_info(cur_time->tm_year); //local time + } + + if( (cal_svc_tm_value.local_dst_offset !=0) && + (__cal_service_compare_date(&cal_svc_tm_value.start_local_dst_date_time,cur_time) > 0) && + (__cal_service_compare_date(cur_time,&cal_svc_tm_value.start_local_std_date_time) > 0) ) + { + *toTime = fromTime+cal_svc_tm_value.local_dst_offset; + } + else + *toTime = fromTime+cal_svc_tm_value.localtime_offset; + + + return CAL_SUCCESS; +CATCH: + + return CAL_ERR_FAIL; + +} + +API int calendar_svc_util_local_to_gmt (time_t fromTime, time_t *toTime) +{ + retex_if(toTime==NULL,,"[ERROR]calendar_svc_util_local_to_gmt:Invalid parameter(toTime)!\n"); + struct tm * cur_time = NULL; + struct tm ttm; + cur_time = gmtime_r(&fromTime,&ttm); + retex_if(cur_time==NULL,,"[ERROR]calendar_svc_util_local_to_gmt:Invalid parameter(fromTime)!\n"); + + + if( (cal_svc_tm_value.is_initialize == false) || + ((cal_svc_tm_value.local_dst_offset !=0) && + (cal_svc_tm_value.start_local_dst_date_time.tm_year != cur_time->tm_year)) ){ + cal_svc_set_tz_base_info(cur_time->tm_year); //local time + } + + if( (cal_svc_tm_value.local_dst_offset !=0) && + (__cal_service_compare_date(&cal_svc_tm_value.start_local_dst_date_time,cur_time) > 0) && + (__cal_service_compare_date(cur_time,&cal_svc_tm_value.start_local_std_date_time) > 0) ) + { + *toTime = fromTime-cal_svc_tm_value.local_dst_offset; + } + else + *toTime = fromTime-cal_svc_tm_value.localtime_offset; + + return CAL_SUCCESS; +CATCH: + + return CAL_ERR_FAIL; +} + +static int get_num(const char *num) +{ + if(NULL == num) + { + return -1; + } + + int temp = 0; + + if(isdigit(num[0])) + { + temp = num[0]-'0'; + } + + if(isdigit(num[1])) + { + temp *= 10; + temp += num[1]-'0'; + } + + return temp; +} + +static int get_week(const char *week) +{ + if(NULL == week) + { + return -1; + } + + switch(week[0]) + { + case 'M': + return 1; + + case 'T': + if(week[1] == 'u') + { + return 2; + } + else if(week[1] == 'h') + { + return 4; + } + else + { + return -1; + } + + case 'W': + return 3; + + case 'F': + return 5; + + case 'S': + if(week[1] == 'a') + { + return 6; + } + else if(week[1] == 'u') + { + return 0; + } + else + return -1; + default: + return -1; + + } + +} + +static int get_month(const char *mon) +{ + if(NULL == mon) + { + return -1; + } + + switch(mon[0]) + { + case 'J': + if(mon[1] == 'a') + { + return 0; + } + else if(mon[1] == 'u') + { + if(mon[2] == 'n') + { + return 5; + } + else + { + return 6; + } + + } + else + { + return -1; + } + + case 'F': + return 1; + + case 'M': + if(mon[2] == 'r') + { + return 2; + } + else if(mon[2] == 'y') + { + return 4; + } + else + { + return -1; + } + + case 'A': + if(mon[1] == 'p') + { + return 3; + } + else if(mon[1] == 'g') + { + return 7; + } + else + { + return -1; + } + + case 'S': + return 8; + + case 'O': + return 9; + + case 'N': + return 10; + + case 'D': + return 11; + + default: + return -1; + + } + +} + +static int get_time(char *line, struct tm* time) +{ + if(NULL == line || NULL == time) + { + return CAL_ERR_FAIL; + } + + char *p = strstr(line," = "); + if(NULL != p) + { + p += 3; + int temp = get_week(p); + if(temp >= 0) + { + time->tm_wday = temp; + } + + p += 4; + temp = get_month(p); + if(temp >= 0) + { + time->tm_mon = temp; + } + + p += 4; + temp = get_num(p); + if(temp >= 0) + { + time->tm_mday = temp; + } + + p += 3; + temp = get_num(p); + if(temp >= 0) + { + time->tm_hour = temp; + } + + p += 3; + temp = get_num(p); + if(temp >= 0) + { + time->tm_min = temp; + } + + p += 3; + temp = get_num(p); + if(temp >= 0) + { + time->tm_sec = temp; + } + + } + + return CAL_SUCCESS; +} + + +static int get_offset(char *line, int *offset) +{ + if(NULL == line || NULL == time) + { + return CAL_ERR_FAIL; + } + + char *p = strstr(line,"gmtoff="); + if(NULL != p) + { + //ERR("%s",p); + p=p+7; + *offset = atoi(p); + } + + return CAL_SUCCESS; +} + + +API int calendar_svc_get_tz_info(char *tz_file_name,int year, struct tm* dst_start, struct tm* dst_end,int *base_offset,int *dst_offset) +{ + CALS_FN_CALL; + char line[1024] = {0}; + char cmd[1024] = {0}; + char year_str[10]= {0}; + bool is_start_time = true; + bool is_set_base_offset = false; + static FILE* fd = NULL; + + retex_if(NULL == tz_file_name || NULL == dst_start || NULL == dst_end,,"Invalid parameter!\n"); + + //start->tm_year = year - 1900; + //end->tm_year = year - 1900; + + snprintf(year_str,sizeof(year_str),"%4d UTC",year); + + snprintf(cmd,sizeof(cmd),"zdump %s -v -c %d,%d",tz_file_name,year-1,year+1); + + if(!(fd = popen(cmd, "r"))) + return CAL_ERR_FAIL; + + while(NULL != fgets(line,sizeof(line)-1,fd)) + { + if(NULL != strstr(line,"isdst=1") && NULL != strstr(line,year_str)) + { + if(is_start_time) + { + is_start_time = false; + get_time(line,dst_start); + dst_start->tm_year = year-1900; + //ERR("%s %d-%d-%d %d",line,dst_start->tm_year,dst_start->tm_mon,dst_start->tm_mday,dst_start->tm_hour); + } + else + { + get_time(line,dst_end); + get_offset(line,dst_offset); + dst_end->tm_year = year-1900; + //ERR("%s %d-%d-%d %d",line,dst_start->tm_year,dst_start->tm_mon,dst_start->tm_mday,dst_start->tm_hour); + } + + } + else if(is_set_base_offset == false) + { + get_offset(line,base_offset); + //is_set_base_offset = true; + } + } + + pclose(fd); + ERR("%s base:%d dst:%d",tz_file_name,*base_offset,*dst_offset); + + return CAL_SUCCESS; + +CATCH: + + return CAL_ERR_FAIL; +} + + +API int calendar_svc_util_convert_db_time (struct tm* fromTime,char *fromTz, struct tm *toTime, char *toTz) +{ + struct tm start_dst_date_time; + struct tm start_std_date_time; + int tz_offset=0; + int dst_offset=0; + time_t base_tt; + struct tm temp_tm; + + retex_if(fromTime==NULL,,"[ERROR]calendar_svc_util_local_to_gmt:Invalid parameter(enddate)!\n"); + retex_if(toTime==NULL,,"[ERROR]calendar_svc_util_local_to_gmt:Invalid parameter(enddate)!\n"); + retex_if(fromTz==NULL,,"[ERROR]calendar_svc_util_local_to_gmt:Invalid parameter(enddate)!\n"); + retex_if(toTz==NULL,,"[ERROR]calendar_svc_util_local_to_gmt:Invalid parameter(enddate)!\n"); + + + base_tt = cals_mktime(fromTime); + if(base_tt < 0) + return 0; + calendar_svc_util_gmt_to_local(base_tt,&base_tt); + cals_tmtime_r(&base_tt,&temp_tm); + + //ERR("temp_tm(%d/%d/%d %d)",temp_tm.tm_year+1900,temp_tm.tm_mon+1,temp_tm.tm_mday,temp_tm.tm_hour); + + if(strcmp(toTz,"GMT")!=0) + { + if(strcmp(toTz,cal_svc_tm_value.local_tz_name) == 0) + { + dst_offset = cal_svc_tm_value.local_dst_offset; + tz_offset = cal_svc_tm_value.localtime_offset; + memcpy(&start_dst_date_time,&cal_svc_tm_value.start_local_dst_date_time,sizeof(struct tm)); + memcpy(&start_std_date_time,&cal_svc_tm_value.start_local_std_date_time,sizeof(struct tm)); + } + else if(strcmp(toTz,cal_svc_tm_value.temp_tz_name) == 0) + { + dst_offset = cal_svc_tm_value.temp_dst_offset; + tz_offset = cal_svc_tm_value.temptime_offset; + memcpy(&start_dst_date_time,&cal_svc_tm_value.start_temp_dst_date_time,sizeof(struct tm)); + memcpy(&start_std_date_time,&cal_svc_tm_value.start_temp_std_date_time,sizeof(struct tm)); + } + else + { + calendar_svc_get_tz_info(toTz,fromTime->tm_year+1900, + &start_dst_date_time, + &start_std_date_time, + &tz_offset,&dst_offset); + } + + if( (dst_offset !=0) && + (__cal_service_compare_date(&start_dst_date_time,&temp_tm) > 0) && + (__cal_service_compare_date(&temp_tm,&start_std_date_time) > 0) ) + { + base_tt = base_tt-dst_offset; + } + else + base_tt = base_tt-tz_offset; + } + + cals_tmtime_r(&base_tt,toTime); + + //ERR("tzinfo(%s:(%d->%d) %d, %d)",toTz,cals_mktime(fromTime),base_tt,tz_offset,dst_offset); + //ERR("fromTime(%d/%d/%d %d)",fromTime->tm_year+1900,fromTime->tm_mon+1,fromTime->tm_mday,fromTime->tm_hour); + //ERR("toTime(%d/%d/%d %d)\n\n",toTime->tm_year+1900,toTime->tm_mon+1,toTime->tm_mday,toTime->tm_hour); + + return CAL_SUCCESS; +CATCH: + + return CAL_ERR_FAIL; +} + + + +API int calendar_svc_util_save_vcs_by_index (const int index, char *full_file_path) +{ + cal_sch_full_t sch_record_fulle = {0}; + int sch_count = 1; + int error_code = 0; + bool is_success = false; + + retv_if(NULL == full_file_path, CAL_ERR_ARG_NULL); + + is_success = cal_db_service_get_record_full_field_by_index(index,&sch_record_fulle,&error_code); + retvm_if(!is_success, error_code, "cal_db_service_get_record_full_field_by_index() Failed(%d)", error_code); + + cal_convert_cal_data_to_vdata_file(&sch_record_fulle,sch_count,full_file_path,&error_code); + cal_db_service_free_full_record(&sch_record_fulle,&error_code); + + return CAL_SUCCESS; +} + +API int calendar_svc_util_register_vcs_file (const char *file_name) +{ + retv_if(NULL == file_name, CAL_ERR_ARG_NULL); + + return cal_vcalendar_register_vcs_file(file_name); +} + +API int calendar_svc_util_convert_vcs_to_event (const char *raw_data,int data_size,cal_struct **record) +{ + CALS_FN_CALL; + //cal_vcalendar_register_vcs_file(file_name); + cal_sch_full_t *sch_array = NULL; + int sch_count = 0; + int error_code = 0; + + retex_if(NULL == record,,"[ERROR]calendar_svc_util_convert_vcs_to_event:Invalid parameter!\n"); + retex_if(NULL == raw_data,,"[ERROR]calendar_svc_util_convert_vcs_to_event:Invalid parameter!\n"); + + bool is_success= FALSE; + is_success = _cal_convert_vcalendar_to_cal_data(raw_data,&sch_array, &sch_count); + + if(is_success) + { + *record = (cal_struct*)malloc(sizeof(cal_struct)); + retex_if(NULL == *record,,"Failed to malloc!\n"); + + (*record)->user_data = sch_array; + //(*record)->event_type = CAL_STRUCT_TYPE_SCHEDULE; + //SURC d.zakutailo 2010-06-03: (*record)->event_type must be obtained from _cal_convert_vcalendar_to_cal_data function. Don't use any predefined types directly. + if (sch_array->cal_type == CAL_EVENT_SCHEDULE_TYPE) { + (*record)->event_type = CAL_STRUCT_TYPE_SCHEDULE; + } else + if (sch_array->cal_type == CAL_EVENT_TODO_TYPE) { + (*record)->event_type = CAL_STRUCT_TYPE_TODO; + } else + (*record)->event_type = sch_array->cal_type; + return CAL_SUCCESS; + } + +CATCH: + + if(NULL != sch_array) + { + cal_db_service_free_full_record(sch_array,&error_code); + CAL_FREE(sch_array); + } + + return CAL_ERR_FAIL; +} + +API int calendar_svc_util_convert_event_to_vcs (cal_struct *record,char **raw_data,int *data_size) +{ + bool is_success= FALSE; + + retv_if(NULL == record, CAL_ERR_ARG_NULL); + retv_if(NULL == raw_data, CAL_ERR_ARG_NULL); + + is_success = _cal_convert_sch_to_vcalendar((cal_sch_full_t*)(record->user_data), 1,raw_data, CAL_VCAL_VER_1_0); + retvm_if(!is_success, CAL_ERR_FAIL, "_cal_convert_sch_to_vcalendar() Failed"); + + return CAL_SUCCESS; +} + +/* will be removed */ +int calendar_svc_util_set_calendar_timezone(const char *tzname) +{ + /* char zoneinfo[256]={0,}; + char cmd[256]={0,}; + sprintf(zoneinfo,"/usr/share/zoneinfo/%s",tzname); + + //calendar_svc_get_time_by_tzinfo(zoneinfo); + //calendar_svc_get_time_by_tzinfo("/usr/share/zoneinfo/calendar_localtime"); + //sprintf(cmd,"rm -f /usr/share/zoneinfo/calendar_localtime"); + unlink("/usr/share/zoneinfo/calendar_localtime"); + sprintf(cmd,"ln -s %s /usr/share/zoneinfo/calendar_localtime",zoneinfo); + execve(cmd);*/ + + return CAL_SUCCESS; +} + +bool cal_svc_util_get_timezone_info(char *city,char **tz_path,char**offset) +{ + int left = 0; + int right = sizeof(time_zone_array)/sizeof(Time_Zone) -1; + int index = 0; + int result = 0; + int max_count = right; + + + while(true) + { + index = ( left + right ) / 2; + + result = strcmp(time_zone_array[index].city, city); + + if(result == 0) + { + *tz_path = strdup(time_zone_array[index].tz_path); + *offset = strdup(time_zone_array[index].gmt); + //DBG("%s,%s,%s,%s",*tz_path,*offset,time_zone_array[index].tz_path,time_zone_array[index].gmt); + break; + } + else if(result < 0) + left = index+1; + else + right = index-1; + + if(left <0 || left >max_count) + goto error; + if(right <0 || right >max_count) + goto error; + if(left > right) + goto error; + + } + + if(*tz_path == NULL) + return false; + else + return true; +error: + *tz_path = NULL; + *offset = NULL; + return false; +} + + +bool cal_svc_util_get_timezone_info_by_tz_path(char *tz_path,char **city_name,char**offset) +{ + int left = 0; + int right = sizeof(tz_path_array)/sizeof(Time_Zone) -1; + int index = 0; + int result = 0; + int max_count = right; + + + while(true) + { + index = ( left + right ) / 2; + + result = strcmp(tz_path_array[index].tz_path, tz_path); + + if(result == 0) + { + *city_name = strdup(tz_path_array[index].city); + *offset = strdup(tz_path_array[index].gmt); + //DBG("%s,%s,%s,%s",*tz_path,*offset,time_zone_array[index].tz_path,time_zone_array[index].gmt); + break; + } + else if(result < 0) + left = index+1; + else + right = index-1; + + if(left <0 || left >max_count) + goto error; + if(right <0 || right >max_count) + goto error; + if(left > right) + goto error; + + } + + if(*city_name == NULL) + return false; + else + return true; +error: + *city_name = NULL; + *offset = NULL; + return false; +} + +void calendar_svc_util_get_city_info(char *tz_path, char**city_name, char**tz_offset) +{ + bool r = false; + if(tz_path == NULL || city_name==NULL || tz_offset == NULL) + return; + + r = cal_svc_util_get_timezone_info_by_tz_path(tz_path,city_name,tz_offset); + if(r){ + ERR("%s,%s,%s",tz_path,*city_name,*tz_offset); + } +} + + +API void calendar_svc_util_get_local_tz_info(char **lock_city_name,char **lock_tz_path,char** lock_tz_offset, + char **local_city_name,char **local_tz_path,char **local_tz_offset) +{ + int lock_on = 0; + bool r = false; + clock_t start_time=0,end_time = 0; + start_time = CAL_PROFILE_GET_TIME(); + + vconf_get_int("db/calendar/timezone_on_off",&lock_on); + + if(lock_on) + { + *lock_city_name = vconf_get_str("db/calendar/timezone"); + r = cal_svc_util_get_timezone_info(*lock_city_name,lock_tz_path,lock_tz_offset); + + if(r){ + ERR("%s,%s,%s",*lock_city_name,*lock_tz_path,*lock_tz_offset); + } + } + else + { + *lock_city_name = NULL; + *lock_tz_path = NULL; + *lock_tz_offset = NULL; + } + + if(*local_tz_path) + { + r = cal_svc_util_get_timezone_info_by_tz_path(*local_tz_path,local_city_name,local_tz_offset); + } + else + { + *local_city_name = vconf_get_str(VCONFKEY_SETAPPL_CITYNAME_INDEX_INT); + cal_svc_util_get_timezone_info(*local_city_name,local_tz_path,local_tz_offset); + } + + if(r){ + ERR("%s,%s,%s",*local_city_name,*local_tz_path,*local_tz_offset); + } + + end_time = CAL_PROFILE_GET_TIME(); + CAL_PROFILE_PRINT(start_time,end_time); + +} + + +/* hidden api */ +API int calendar_svc_get_month_event_list (int account_id, time_t startdate, time_t enddate,int is_repeat, cal_iter **iter) +{ + CALS_FN_CALL; + int ret; + sqlite3_stmt *stmt = NULL; + + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + + *iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == *iter, CAL_ERR_OUT_OF_MEMORY, "calloc() Failed(%d)", errno); + + ret = cal_db_service_get_month_event(account_id, startdate, enddate, is_repeat, &stmt); + if (CAL_SUCCESS != ret) { + ERR("cal_db_service_get_month_event() Failed(%d)", ret); + free(*iter); + *iter = NULL; + return ret; + } + + (*iter)->is_patched = FALSE; + (*iter)->stmt = stmt; + (*iter)->i_type = CAL_STRUCT_TYPE_SCHEDULE; + + return CAL_SUCCESS; +} + +API int calendar_svc_iter_get_month_info (cal_iter *iter, int is_repeat,cal_struct **row_event) +{ + CALS_FN_CALL; + cal_sch_full_t *sch_record = NULL; + + retv_if(NULL == iter, CAL_ERR_ARG_NULL); + retv_if(NULL == iter->stmt, CAL_ERR_ARG_NULL); + retv_if(NULL == row_event, CAL_ERR_ARG_NULL); + + if(iter->is_patched!=TRUE) + { + int ret = calendar_svc_iter_next(iter); + if(ret == CAL_ERR_FINISH_ITER) + return CAL_ERR_NO_DATA; + else if(ret != CAL_SUCCESS) + return ret; + } + + int error_code = 0; + + if(*row_event == NULL) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_SCHEDULE); + retvm_if(NULL == *row_event, CAL_ERR_OUT_OF_MEMORY, "calendar_svc_struct_new() Failed"); + + (*row_event)->event_type = CAL_STRUCT_TYPE_SCHEDULE; + } + sch_record = (cal_sch_full_t*)(*row_event)->user_data; + retv_if(NULL == sch_record, CAL_ERR_FAIL); + + cal_db_service_convert_stmt_to_month_field_record(iter->stmt,is_repeat,sch_record,true); + + if(is_repeat) + cal_db_service_get_recurrency_exception(sch_record->index,&(sch_record->exception_date_list),&error_code); + + + return CAL_SUCCESS; +} + +static inline void __set_day_flag(struct tm*stm,struct tm*etm,struct tm*estm,struct tm*eetm,int *day_flag) +{ + + int start_day = 0; + int end_day = 0; + int i = 0; + + //ERR("stm(%d/%d/%d %d)",stm->tm_year+1900,stm->tm_mon+1,stm->tm_mday,stm->tm_hour); + //ERR("etm(%d/%d/%d %d)",etm->tm_year+1900,etm->tm_mon+1,etm->tm_mday,etm->tm_hour); + //ERR("estm(%d/%d/%d %d)",estm->tm_year+1900,estm->tm_mon+1,estm->tm_mday,estm->tm_hour); + //ERR("eetm(%d/%d/%d %d)",eetm->tm_year+1900,eetm->tm_mon+1,eetm->tm_mday,eetm->tm_hour); + + int istm = 0; + int ietm = 0; + int iestm = 0; + int ieetm = 0; + + istm = timegm(stm)/ONE_DAY_SECONDS; + ietm = timegm(etm)/ONE_DAY_SECONDS; + iestm = timegm(estm)/ONE_DAY_SECONDS; + ieetm = timegm(eetm)/ONE_DAY_SECONDS; + + if(ieetmietm) + return; + + if(iestm account_id,,"[ERROR]calendar_svc_get_event_list_by_period:Invalid parameter(account_id)!\n"); + retvm_if(startdate < 0, CAL_ERR_ARG_INVALID, "startdate(%d) is Invalid", startdate); + retvm_if(enddate < 0, CAL_ERR_ARG_INVALID, "enddate(%d) is Invalid", enddate); + + localtime_r(&startdate, &stm); + localtime_r(&enddate, &etm); + + //localtime_r(&startdate,&stm); + //localtime_r(&enddate,&etm); + + if(etm.tm_mon != stm.tm_mon) + { + enddate--; + localtime_r(&enddate,&etm); + //cals_tmtime_r(&enddate, &etm); + } + + + //no repeat event + calendar_svc_get_month_event_list(account_id, startdate, enddate,false,&it); + + while (calendar_svc_iter_next(it) == CAL_SUCCESS) { + rc = calendar_svc_iter_get_month_info(it, false,&cs); + if (rc != CAL_SUCCESS || cs == NULL) + break; + + temp_tm = calendar_svc_struct_get_tm(cs, CAL_VALUE_GMT_START_DATE_TIME,CAL_TZ_FLAG_LOCAL); + memcpy(&estm,temp_tm,sizeof(struct tm)); + temp_tm = calendar_svc_struct_get_tm(cs, CAL_VALUE_GMT_END_DATE_TIME,CAL_TZ_FLAG_LOCAL); + memcpy(&eetm,temp_tm,sizeof(struct tm)); + __set_day_flag(&stm,&etm,&estm,&eetm,day_flag); + + calendar_svc_struct_free(&cs); + } + + calendar_svc_iter_remove(&it); + it = NULL; + + //repeat event + calendar_svc_get_month_event_list(account_id, startdate, enddate,true,&it); + + while (calendar_svc_iter_next(it) == CAL_SUCCESS) { + rc = calendar_svc_iter_get_month_info(it,true, &cs); + if (rc != CAL_SUCCESS || cs == NULL) + break; + + memset(&lstm,0x00,sizeof(struct tm)); + memset(&letm,0x00,sizeof(struct tm)); + + while (calendar_svc_util_next_valid_event_tm(cs, + &stm, &etm, &lstm, &letm) == CAL_SUCCESS) { + __set_day_flag(&stm,&etm,&lstm,&letm,day_flag); + + } + calendar_svc_struct_free(&cs); + } + calendar_svc_iter_remove(&it); + + return CAL_SUCCESS; +} + + +API int calendar_svc_iter_get_main_info (cal_iter *iter, cal_struct **row_event) +{ + CALS_FN_CALL; + int ret; + calendar_t *cal_record = NULL; + cal_sch_full_t *sch_record = NULL; + cal_timezone_t *tz_record = NULL; + int error_code = 0; + + retv_if(iter == NULL, CAL_ERR_ARG_NULL); + retv_if(iter->stmt == NULL, CAL_ERR_ARG_INVALID); + retv_if(NULL == row_event, CAL_ERR_ARG_NULL); + + if(iter->is_patched!=TRUE) + { + int ret = calendar_svc_iter_next(iter); + if(ret == CAL_ERR_FINISH_ITER) + { + return CAL_ERR_NO_DATA; + } + else if(ret != CAL_SUCCESS) + { + return ret; + } + } + + switch(iter->i_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + if(*row_event == NULL) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_SCHEDULE); + retvm_if(NULL == *row_event, CAL_ERR_OUT_OF_MEMORY, "calendar_svc_struct_new() Failed"); + + (*row_event)->event_type = CAL_STRUCT_TYPE_SCHEDULE; + } + sch_record = (cal_sch_full_t*)(*row_event)->user_data; + retv_if(NULL == sch_record, CAL_ERR_ARG_NULL); + + cals_stmt_get_full_schedule(iter->stmt, sch_record, true); + + cal_db_service_get_participant_info_by_index(sch_record->index,&(sch_record->attendee_list),&error_code); + cal_db_service_get_meeting_category_info_by_index(sch_record->index,&(sch_record->meeting_category),&error_code); + cal_db_service_get_recurrency_exception(sch_record->index,&(sch_record->exception_date_list),&error_code); + ret = cals_get_alarm_info(sch_record->index, &(sch_record->alarm_list)); + retvm_if(CAL_SUCCESS != ret, ret, "cals_get_alarm_info() Failed(%d)", ret); + + break; + case CAL_STRUCT_TYPE_TODO: + if(*row_event == NULL) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_TODO); + retvm_if(NULL == *row_event, CAL_ERR_OUT_OF_MEMORY, "calendar_svc_struct_new() Failed"); + + (*row_event)->event_type = CAL_STRUCT_TYPE_TODO; + } + sch_record = (cal_sch_full_t*)(*row_event)->user_data; + retv_if(NULL == sch_record, CAL_ERR_ARG_NULL); + + cals_stmt_get_full_schedule(iter->stmt, sch_record, true); + + break; + + case CAL_STRUCT_TYPE_CALENDAR: + if(*row_event == NULL) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_CALENDAR); + retvm_if(NULL == *row_event, CAL_ERR_OUT_OF_MEMORY, "calendar_svc_struct_new() Failed"); + + (*row_event)->event_type = CAL_STRUCT_TYPE_CALENDAR; + } + cal_record = (calendar_t*)(*row_event)->user_data; + retv_if(NULL == cal_record, CAL_ERR_FAIL); + + cals_stmt_get_calendar(iter->stmt,cal_record); + + break; + case CAL_STRUCT_TYPE_TIMEZONE: + if(*row_event == NULL) + { + *row_event = calendar_svc_struct_new(CAL_STRUCT_TIMEZONE); + retvm_if(NULL == *row_event, CAL_ERR_OUT_OF_MEMORY, "calendar_svc_struct_new() Failed"); + + (*row_event)->event_type = CAL_STRUCT_TYPE_TIMEZONE; + } + tz_record = (cal_timezone_t*)(*row_event)->user_data; + retv_if(NULL == tz_record, CAL_ERR_FAIL); + + cal_db_service_convert_stmt_to_tz_info(iter->stmt,tz_record); + + break; + + default: + break; + } + + return CAL_SUCCESS; +} diff --git a/src/cals-recurrence-utils.c b/src/cals-recurrence-utils.c new file mode 100755 index 0000000..8e45921 --- /dev/null +++ b/src/cals-recurrence-utils.c @@ -0,0 +1,1229 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include + +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-recurrence-utils.h" +#include "cals-utils.h" +#include "cals-tz-utils.h" + +int calendar_svc_get_tz_info(char *tz_file_name,int year, struct tm* dst_start, struct tm* dst_end,int *base_offset,int *dst_offset); + +static const UINT8 month_table[12]={31,28,31,30,31,30,31,31,30,31,30,31}; + +//this array is used to calculate the day numer of a month in a year +static const UINT16 days_table[12] = { + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, +}; + +//const static int _lpdays[] = { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; +//const static int _days[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }; + + +#define is_leap_year_tm(y) (((y+1900)%4 == 0 && ((y+1900)%100 != 0 || (y+1900)%400 == 0))? 1 : 0) + +static UINT32 g_cal_cur_id = -1; +//cal_date_param_t cal_date_param={0,}; + +#ifndef SECOFONEDAY +#define SECOFONEDAY 86400 +#endif + +extern cal_svc_tm_info_t cal_svc_tm_value; + +static CAL_GET_VALID_DATE_FUNC cal_service_get_valid_date_func[] = +{ + cal_service_get_next_repeat_none_valid_date, + cal_service_get_next_repeat_daily_valid_date, + cal_service_get_next_repeat_weekly_valid_date, + cal_service_get_next_repeat_monthly_valid_date, + cal_service_get_next_repeat_yearly_valid_date, + cal_service_get_next_repeat_weekly_valid_date, + cal_service_get_next_repeat_monthly_valid_date, + cal_service_get_next_repeat_yearly_valid_date, +}; + + +/** + * compare two days + * return -1 : adate is later then bdate + * 0 : adate is the same with bdate + * 1 : adate is earlier then bdate + */ +INT8 __cal_service_compare_date(const struct tm *first_date,const struct tm *second_date) +{ + UINT32 int_date_one = 0 ,int_date_two = 0; + + retvm_if(NULL == first_date, false, "\n %s:argument is NULL",__FUNCTION__); + retvm_if(NULL == second_date, false, "\n %s:argument is NULL",__FUNCTION__); + + int_date_one = (first_date->tm_year*10000)+(first_date->tm_mon*100)+first_date->tm_mday; + int_date_two = (second_date->tm_year*10000)+(second_date->tm_mon*100)+second_date->tm_mday; + + if( int_date_one == int_date_two ) + { + return 0; + } + else if( int_date_one > int_date_two ) + { + return -1; + } + + return 1; +} + + +static void __cal_service_get_day_after_num(struct tm *start_day,struct tm *after_day,int day) +{ + time_t base_time = 0; + retm_if(NULL == start_day, "\n %s:argument is NULL",__FUNCTION__); + retm_if(NULL == after_day, "\n %s:argument is NULL",__FUNCTION__); + + base_time = cals_mktime(start_day); + base_time = base_time + (day * SECOFONEDAY); + + memcpy(after_day,cals_tmtime(&base_time),sizeof(struct tm)); +} + +static void __cal_service_get_day_after_sec(struct tm *start_day,struct tm *after_day,int sec) +{ + time_t base_time = 0; + retm_if(NULL == start_day, "\n %s:argument is NULL",__FUNCTION__); + retm_if(NULL == after_day, "\n %s:argument is NULL",__FUNCTION__); + + base_time = cals_mktime(start_day); + base_time = base_time + (sec); + + memcpy(after_day,cals_tmtime(&base_time),sizeof(struct tm)); +} + +static int __cal_service_get_num_of_event_day(struct tm *start_date, struct tm *end_date) +{ + struct tm start_buf={0,}; + struct tm end_buf={0,}; + retvm_if(NULL == start_date, false, "\n %s:argument is NULL",__FUNCTION__); + retvm_if(NULL == end_date, false, "\n %s:argument is NULL",__FUNCTION__); + + //compare date only + memcpy(&start_buf,start_date,sizeof(struct tm)); + memcpy(&end_buf,end_date,sizeof(struct tm)); + + start_buf.tm_hour = 0; + start_buf.tm_min = 0; + start_buf.tm_sec = 0; + + end_buf.tm_hour = 0; + end_buf.tm_min = 0; + end_buf.tm_sec = 0; + + + return ((cals_mktime(&end_buf) - cals_mktime(&start_buf)) /SECOFONEDAY); +} +/* + void + cal_service_get_day_after_num(cal_service_date_t *start_day,cal_service_date_t *after_day,int day) + { + __cal_service_get_day_after_num(start_day,after_day,day); + }*/ + +void cal_service_set_day_of_week(struct tm* tm) +{ + int days = 0; + int year = 0; + int month = 0; + retm_if(NULL == tm, "\n %s:argument is NULL",__FUNCTION__); + days = tm->tm_mday; + year = tm->tm_year+1900; + month = tm->tm_mon; + + days=(year-1)+(year-1)/4-(year-1)/100+(year-1)/400 + days_table[month] + tm->tm_mday + ( (month>1) ? is_leap_year_tm(year) : 0 ) ; + tm->tm_wday = days%7; +} + +/* +/// just refer +void __cal_service_convert_datetime_to_tm(struct tm *date,struct tm *tm) +{ +tm->tm_year = date->date.tm_year-BENCHMARK_YEAR; +tm->tm_mon = date->date.month-1; +tm->tm_mday = date->date.tm_mday; +tm->tm_wday = date->date.wday; +tm->tm_hour = date->time.hours; +tm->tm_min = date->time.minutes; +tm->tm_sec = date->time.seconds; +} + +void __cal_service_convert_tm_to_datetime(struct tm *tm,struct tm *date) +{ +date->date.tm_year =tm->tm_year+BENCHMARK_YEAR; +date->date.month = tm->tm_mon+1; +date->date.tm_mday = tm->tm_mday; +date->date.wday =tm->tm_wday; +date->time.hours = tm->tm_hour; +date->time.minutes = tm->tm_min; +date->time.seconds = tm->tm_sec; +} + + +bool +cal_db_service_adjust_time(struct tm* pDateTime, long adjustment) +{ +time_t base_time = cals_mktime(pDateTime); + +base_time = base_time+adjustment; +memcpy(pDateTime,cals_tmtime(&base_time),sizeof(struct tm)); + +return true; +} +*/ + + +bool cal_is_used_dst_timezone(cal_sch_full_t *sch_record) +{ + + return false; +} + +void cal_svc_set_tz_base_info(int year) +{ + char *tz_name = NULL; + char * lock_city_name= NULL; + char * lock_tz_path= NULL; + char * lock_tz_offset= NULL; + char * local_city_name= NULL; + char * local_tz_path= NULL; + char * local_tz_offset= NULL; + + //temp(test code) + //local_tz_path=strdup("Asia/Seoul"); + + calendar_svc_util_get_local_tz_info(&lock_city_name,&lock_tz_path,&lock_tz_offset,&local_city_name,&local_tz_path,&local_tz_offset); + + + if(lock_tz_path) + tz_name = lock_tz_path; + else if(local_tz_path) + tz_name = local_tz_path; + else + tz_name = "localtime"; + + + + if(cal_svc_tm_value.is_initialize == FALSE || year != cal_svc_tm_value.start_local_dst_date_time.tm_year) + { + calendar_svc_get_tz_info(tz_name,year+1900, + &cal_svc_tm_value.start_local_dst_date_time, + &cal_svc_tm_value.start_local_std_date_time, + &cal_svc_tm_value.localtime_offset,&cal_svc_tm_value.local_dst_offset); + + cal_svc_tm_value.is_initialize = true; + strncpy(cal_svc_tm_value.local_tz_name,tz_name, sizeof(cal_svc_tm_value.local_tz_name)); + } + + + CAL_FREE(lock_city_name); + CAL_FREE(lock_tz_path); + CAL_FREE(lock_tz_offset); + CAL_FREE(local_city_name); + CAL_FREE(local_tz_path); + CAL_FREE(local_tz_offset); +} + +bool cal_get_dst_info_time(cal_date_param_t *cal_date_param,const cal_sch_full_t *sch_record) +{ + int dst_offset = 0; + + retvm_if(NULL == cal_date_param, false, "\n %s:argument is NULL",__FUNCTION__); + retvm_if(NULL == sch_record, false, "\n %s:argument is NULL",__FUNCTION__); + + if(cal_svc_tm_value.is_initialize == false){ + time_t t = time(NULL); + struct tm * cur_time = NULL;//localtime(&t); + struct tm ttm; + + cur_time = localtime_r(&t,&ttm); + + if(cur_time) + cal_svc_set_tz_base_info(cur_time->tm_year); //local time + } + + if(sch_record->tz_name == NULL || sch_record->tz_name[0] == '\0') + { + strncpy(cal_svc_tm_value.temp_tz_name,"calendar_localtime", sizeof(cal_svc_tm_value.temp_tz_name)); + dst_offset = cal_svc_tm_value.temp_dst_offset = cal_svc_tm_value.local_dst_offset; + cal_svc_tm_value.temptime_offset = cal_svc_tm_value.localtime_offset; + memcpy(&cal_svc_tm_value.start_temp_dst_date_time,&cal_svc_tm_value.start_local_dst_date_time,sizeof(struct tm)); + memcpy(&cal_svc_tm_value.start_temp_std_date_time,&cal_svc_tm_value.start_local_std_date_time,sizeof(struct tm)); + } + else + { + + if( (strcmp(cal_svc_tm_value.temp_tz_name,sch_record->tz_name)==0) && + ((cal_svc_tm_value.temp_dst_offset ==0) || + ((cal_svc_tm_value.temp_dst_offset !=0) && + (cal_svc_tm_value.start_temp_dst_date_time.tm_year == cal_date_param->start_db_date_time.tm_year)))) + { + cal_date_param->dbtime_offset = cal_svc_tm_value.temptime_offset; + dst_offset = cal_date_param->db_dst_offset = cal_svc_tm_value.temp_dst_offset; + memcpy(&cal_date_param->start_db_dst_date_time,&cal_svc_tm_value.start_temp_dst_date_time,sizeof(struct tm)); + memcpy(&cal_date_param->start_db_std_date_time,&cal_svc_tm_value.start_temp_std_date_time,sizeof(struct tm)); + } + else { + calendar_svc_get_tz_info(sch_record->tz_name,cal_date_param->start_db_date_time.tm_year+1900, + &cal_date_param->start_db_dst_date_time, + &cal_date_param->start_db_std_date_time, + &cal_date_param->dbtime_offset,&cal_date_param->db_dst_offset); + + strncpy(cal_svc_tm_value.temp_tz_name,sch_record->tz_name,sizeof(cal_svc_tm_value.temp_tz_name)); + dst_offset = cal_svc_tm_value.temp_dst_offset = cal_date_param->db_dst_offset; + cal_svc_tm_value.temptime_offset = cal_date_param->dbtime_offset; + memcpy(&cal_svc_tm_value.start_temp_dst_date_time,&cal_date_param->start_db_dst_date_time,sizeof(struct tm)); + memcpy(&cal_svc_tm_value.start_temp_std_date_time,&cal_date_param->start_db_std_date_time,sizeof(struct tm)); + } + } + + if(dst_offset == 0) + return false; + else + return true; +} + + +void cal_set_time_by_dst_info(cal_date_param_t *cal_date_param,const cal_sch_full_t *sch_record,struct tm *next_start_tm,struct tm *next_end_tm) +{ + retm_if(NULL == cal_date_param, "\n %s:argument is NULL",__FUNCTION__); + retm_if(NULL == sch_record, "\n %s:argument is NULL",__FUNCTION__); + retm_if(NULL == next_start_tm, "\n %s:argument is NULL",__FUNCTION__); + retm_if(NULL == next_end_tm, "\n %s:argument is NULL",__FUNCTION__); + + if(cal_date_param->is_need_adjust_time_for_view == DB_STD_LOCAL_STD || + cal_date_param->is_need_adjust_time_for_view == DB_INDST_LOCAL_DST || + cal_date_param->is_need_adjust_time_for_view == DB_OUTDST_LOCAL_DST || + (sch_record->repeat_term == CAL_REPEAT_NONE) || + (sch_record->all_day_event == TRUE) ) + { + cal_date_param->i_adjust_time_value = 0; + memcpy(next_start_tm,&cal_date_param->start_local_date_time,sizeof(struct tm)); + memcpy(next_end_tm,&cal_date_param->end_local_date_time,sizeof(struct tm)); + return; + } + + if(cal_date_param->is_need_adjust_time_for_view == DB_STD_LOCAL_DST) + { + cal_svc_set_tz_base_info(cal_date_param->start_local_date_time.tm_year); + + if( (__cal_service_compare_date(&cal_svc_tm_value.start_local_dst_date_time,&cal_date_param->start_local_date_time) > 0) && + (__cal_service_compare_date(&cal_date_param->start_local_date_time,&cal_svc_tm_value.start_local_std_date_time) > 0) + ) + { + /* if current local date is exist in DST Time period - adjust +1 hours */ + cal_date_param->i_adjust_time_value = 1; + __cal_service_get_day_after_sec(&cal_date_param->start_local_date_time,next_start_tm,SECSPERHOUR*cal_date_param->i_adjust_time_value); + __cal_service_get_day_after_sec(&cal_date_param->end_local_date_time,next_end_tm,SECSPERHOUR*cal_date_param->i_adjust_time_value); + + } + else + { + /* if current local date is exist out DST Time period - do not need adjustment */ + memcpy(next_start_tm,&cal_date_param->start_local_date_time,sizeof(struct tm)); + memcpy(next_end_tm,&cal_date_param->end_local_date_time,sizeof(struct tm)); + } + + } + else if(cal_date_param->is_need_adjust_time_for_view == DB_INDST_LOCAL_STD) + { + cal_get_dst_info_time(cal_date_param,sch_record); + + /* check startDstTimeDate < srcTimeDate < startStdTimeDate */ + if( (__cal_service_compare_date(&cal_date_param->start_db_dst_date_time,&cal_date_param->start_db_date_time) > 0) && + (__cal_service_compare_date(&cal_date_param->start_db_date_time,&cal_date_param->start_db_std_date_time) > 0) + ) + { + /* if current local date is exist in DST Time period - do not need adjustment*/ + memcpy(next_start_tm,&cal_date_param->start_local_date_time,sizeof(struct tm)); + memcpy(next_end_tm,&cal_date_param->end_local_date_time,sizeof(struct tm)); + } + else + { + /* if current local date is exist out DST Time period - adjust +1 hours */ + cal_date_param->i_adjust_time_value = 1; + __cal_service_get_day_after_sec(&cal_date_param->start_local_date_time,next_start_tm,SECSPERHOUR*cal_date_param->i_adjust_time_value); + __cal_service_get_day_after_sec(&cal_date_param->end_local_date_time,next_end_tm,SECSPERHOUR*cal_date_param->i_adjust_time_value); + + + } + + } + else /* DB_OUTDST_LOCAL_STD */ + { + cal_get_dst_info_time(cal_date_param,sch_record); + + /* check startDstTimeDate < srcTimeDate < startStdTimeDate */ + if( (__cal_service_compare_date(&cal_date_param->start_db_dst_date_time,&cal_date_param->start_db_date_time) > 0) && + (__cal_service_compare_date(&cal_date_param->start_db_date_time,&cal_date_param->start_db_std_date_time) > 0) + ) + { + /* if current local date is exist in DST Time period - adjust -1 hours */ + cal_date_param->i_adjust_time_value = -1; + __cal_service_get_day_after_sec(&cal_date_param->start_local_date_time,next_start_tm,SECSPERHOUR*cal_date_param->i_adjust_time_value); + __cal_service_get_day_after_sec(&cal_date_param->end_local_date_time,next_end_tm,SECSPERHOUR*cal_date_param->i_adjust_time_value); + + + } + else + { + /* if current local date is exist out DST Time period - do not need adjustment*/ + memcpy(next_start_tm,&cal_date_param->start_local_date_time,sizeof(struct tm)); + memcpy(next_end_tm,&cal_date_param->end_local_date_time,sizeof(struct tm)); + } + } +} + +void __cal_service_reset_exception_date_info(cal_date_param_t *cal_date_param ) +{ + GList *head; + cal_value *value = NULL; + if(cal_date_param->exception_date_list) + { + head = cal_date_param->exception_date_list; + while (cal_date_param->exception_date_list) + { + value = cal_date_param->exception_date_list->data; + if(NULL != value) + { + if(NULL != value->user_data) + { + CAL_FREE(value->user_data); + } + CAL_FREE(value); + } + cal_date_param->exception_date_list = cal_date_param->exception_date_list->next; + } + g_list_free(head); + cal_date_param->exception_date_list = NULL; + } +} + +void __cal_service_set_exception_date_info(cal_date_param_t *cal_date_param,cal_sch_full_t *sch_record) +{ + GList *head=NULL; + GList *desc=NULL; + + cal_value *value = NULL; + cal_value *desc_value = NULL; + cal_exception_info_t* desc_exception = NULL; + time_t exception_tt,temp_time; + + if(sch_record->exception_date_list) + { + head = sch_record->exception_date_list; + while (head) + { + value = head->data; + if(NULL != value) + { + if(value->user_data) + { + desc_value = (cal_value*)malloc(sizeof(cal_value)); + retm_if(NULL == desc_value,"[ERROR]__cal_service_set_exception_date_info:Failed to malloc!\n"); + + desc_value->v_type = CAL_EVENT_RECURRENCY; + desc_exception = desc_value->user_data = (cal_exception_info_t*)malloc(sizeof(cal_exception_info_t)); + retm_if(NULL == desc_exception,"[ERROR]__cal_service_set_exception_date_info:Failed to malloc!\n"); + + exception_tt = cals_mktime(&(((cal_exception_info_t*)(value->user_data))->exception_start_time)); + temp_time = exception_tt + cal_svc_tm_value.temptime_offset; //db timezone + cals_tmtime_r(&temp_time,&(desc_exception->exception_start_time)); + ERR("exception date(%d/%d/%d %d)",desc_exception->exception_start_time.tm_year+1900,desc_exception->exception_start_time.tm_mon+1,desc_exception->exception_start_time.tm_mday,desc_exception->exception_start_time.tm_hour); + + } + } + head = head->next; + desc = g_list_append(desc,desc_value); + } + cal_date_param->exception_date_list = desc; + } + +} + +void cal_service_set_date_param(cal_date_param_t *cal_date_param,cal_sch_full_t *sch_record) +{ + time_t temp_time; + time_t end_time = 0; + time_t start_time = 0; + time_t repeat_end_time = 0; + retm_if(NULL == cal_date_param, "\n %s:argument is NULL",__FUNCTION__); + retm_if(NULL == sch_record, "\n %s:argument is NULL",__FUNCTION__); + //bool is_used_dst_db_timezone = false; + //bool is_used_dst_local_timezone = false; + extern cal_svc_tm_info_t cal_svc_tm_value; + + __cal_service_reset_exception_date_info(cal_date_param); + memset(cal_date_param,0x00,sizeof(cal_date_param_t)); + + memcpy(&(cal_date_param->start_db_date_time),&(sch_record->start_date_time),sizeof(struct tm)); + memcpy(&(cal_date_param->end_db_date_time),&(sch_record->end_date_time),sizeof(struct tm)); + memcpy(&(cal_date_param->start_local_date_time),&(sch_record->start_date_time),sizeof(struct tm)); + memcpy(&(cal_date_param->end_local_date_time),&(sch_record->end_date_time),sizeof(struct tm)); + + memcpy(&(cal_date_param->repeat_end_date),&(sch_record->repeat_end_date),sizeof(struct tm)); + + cal_get_dst_info_time(cal_date_param,sch_record); + + __cal_service_set_exception_date_info(cal_date_param,sch_record); + + if(sch_record->all_day_event == true) + goto COMMON; + cal_date_param->repeat_end_date.tm_hour = cal_date_param->start_db_date_time.tm_hour; + cal_date_param->repeat_end_date.tm_min = cal_date_param->start_db_date_time.tm_min; + cal_date_param->repeat_end_date.tm_sec = cal_date_param->start_db_date_time.tm_sec; + + start_time = cals_mktime(&(cal_date_param->start_db_date_time)); + end_time = cals_mktime(&(cal_date_param->end_db_date_time)); + repeat_end_time = cals_mktime(&(cal_date_param->repeat_end_date)); + + temp_time = start_time + cal_svc_tm_value.temptime_offset; + //calendar_svc_util_local_to_gmt(start_time, &temp_time); + cals_tmtime_r(&temp_time,&(cal_date_param->start_db_date_time)); + + temp_time = end_time + cal_svc_tm_value.temptime_offset; + //calendar_svc_util_local_to_gmt(end_time, &temp_time); + cals_tmtime_r(&temp_time,&(cal_date_param->end_db_date_time)); + + temp_time = repeat_end_time + cal_svc_tm_value.temptime_offset; + cals_tmtime_r(&temp_time,&(cal_date_param->repeat_end_date)); + + + start_time = cals_mktime(&(cal_date_param->start_local_date_time)); + end_time = cals_mktime(&(cal_date_param->end_local_date_time)); + + //if(sch_record->repeat_term == CAL_REPEAT_NONE) + calendar_svc_util_gmt_to_local(start_time, &temp_time); + cals_tmtime_r(&temp_time,&(cal_date_param->start_local_date_time)); + + + calendar_svc_util_gmt_to_local(end_time, &temp_time); + cals_tmtime_r(&temp_time,&(cal_date_param->end_local_date_time)); + + if(cal_svc_tm_value.temp_dst_offset!=0) + { + /* check startDstTimeDate < srcTimeDate < startStdTimeDate */ + if( (__cal_service_compare_date(&cal_date_param->start_db_dst_date_time,&cal_date_param->start_db_date_time) > 0) && + (__cal_service_compare_date(&cal_date_param->start_db_date_time,&cal_date_param->start_db_std_date_time) > 0) + ) /* dbtimezone is dst timezone */ + { + if(cal_svc_tm_value.local_dst_offset!=0) + { + __cal_service_get_day_after_sec(&cal_date_param->start_local_date_time,&cal_date_param->start_local_date_time,SECSPERHOUR); + __cal_service_get_day_after_sec(&cal_date_param->end_local_date_time,&cal_date_param->end_local_date_time,SECSPERHOUR); + cal_date_param->is_need_adjust_time_for_view = DB_INDST_LOCAL_DST; + + }else + { + /* need adjust, after computation */ + cal_date_param->is_need_adjust_time_for_view = DB_INDST_LOCAL_STD; + } + } + else /* dbtimezone is not dst timezone */ + { + if(cal_svc_tm_value.local_dst_offset!=0) + { + /* nothing */ + cal_date_param->is_need_adjust_time_for_view = DB_OUTDST_LOCAL_DST; + } + else + { + /* need adjust, after computation */ + cal_date_param->is_need_adjust_time_for_view = DB_OUTDST_LOCAL_STD; + } + } + }else + { + if(cal_svc_tm_value.local_dst_offset!=0) + { + /* need adjust, after computation */ + cal_date_param->is_need_adjust_time_for_view = DB_STD_LOCAL_DST; + }else + { + /* nothing */ + cal_date_param->is_need_adjust_time_for_view = DB_STD_LOCAL_STD; + } + } + +COMMON: + + g_cal_cur_id = -2; + if(cal_date_param->repeat_end_date.tm_year >137) + { + cal_date_param->repeat_end_date.tm_year = 137; + } + + cal_date_param->prev_alarm_time.tm_year = 9999; + cal_date_param->repeat_by_set_position = (cal_date_param->start_db_date_time.tm_mday - 1) /7 + 1; + +} + + + +/* API for calculate date return TRUE is valid DATE, FALSE is not valid date */ +BOOL cal_service_get_next_repeat_none_valid_date(const cal_sch_full_t *sch_record, + cal_date_param_t *cal_date_param,struct tm *now_start_date,struct tm *now_end_date) +{ + retvm_if(NULL == sch_record, false, "sch_record is NULL"); + retvm_if(NULL == cal_date_param, false, "cal_date_param is NULL"); + retvm_if(NULL == now_start_date, false, "now_start_date is NULL"); + retvm_if(NULL == now_end_date, false, "now_end_date is NULL"); + + /* localend_date < nowStartDate || nowEndDate < localStartDate */ + memcpy(&cal_date_param->prev_alarm_time,&cal_date_param->start_local_date_time,sizeof(struct tm)); + + /* never call this function with same id */ + if (g_cal_cur_id == sch_record->index) + { + return FALSE; + } + + if ((__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0) + || (__cal_service_compare_date(now_end_date,&(cal_date_param->start_local_date_time)) > 0) ) + { + g_cal_cur_id = -1; + return FALSE; + } + + g_cal_cur_id = sch_record->index; + + return TRUE; +} + +BOOL cal_service_get_next_repeat_daily_valid_date(const cal_sch_full_t *sch_record, + cal_date_param_t *cal_date_param, struct tm *now_start_date, struct tm *now_end_date) +{ + UINT32 count_day=0; + retvm_if(NULL == sch_record, false, "sch_record is NULL"); + retvm_if(NULL == cal_date_param, false, "cal_date_param is NULL"); + retvm_if(NULL == now_start_date, false, "now_start_date is NULL"); + retvm_if(NULL == now_end_date, false, "now_end_date is NULL"); + + if (sch_record->repeat_interval == 0) + { + return FALSE; /* invalid Data */ + } + + /* first function call & valid date check */ + if ( (g_cal_cur_id != sch_record->index) && + ( !( (__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0 ) + || (__cal_service_compare_date(&(cal_date_param->start_local_date_time),now_end_date) < 0 ) ) + ) ) + { + g_cal_cur_id = sch_record->index; + } + else + { + //TODO: need improvement performance + + do + { + count_day = 0; + count_day = count_day + sch_record->repeat_interval; + __cal_service_get_day_after_num(&(cal_date_param->start_db_date_time),&(cal_date_param->start_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_db_date_time),&(cal_date_param->end_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->start_local_date_time),&(cal_date_param->start_local_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_local_date_time),&(cal_date_param->end_local_date_time),count_day); + }while( (__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0)); + + g_cal_cur_id = sch_record->index; + } + + //__cal_service_convert_tm_to_date(&(sch_record->repeat_end_date), &repeat_end_date); + /*check again*/ + if ((__cal_service_compare_date(&(cal_date_param->repeat_end_date),&(cal_date_param->start_db_date_time)) > 0 ) + || (__cal_service_compare_date(&(cal_date_param->start_local_date_time),now_end_date) < 0 )) + { + g_cal_cur_id = -1; + return FALSE; + } + + return TRUE; +} + +BOOL cal_service_get_next_repeat_weekly_valid_date(const cal_sch_full_t *sch_record, + cal_date_param_t *cal_date_param, struct tm *now_start_date, struct tm *now_end_date) +{ + + UINT8 valid_week[7]={0,}; + UINT32 count_day=0; + int week_count=0; + int i = 0; + static BOOL is_same_start_day_of_week =TRUE; + static UINT8 start_day_of_week=0; + BOOL is_first_valid_date = TRUE; + BOOL is_set_week_flag = FALSE; + retvm_if(NULL == sch_record, false, "\n %s:argument is NULL",__FUNCTION__); + retvm_if(NULL == cal_date_param, false, "\n %s:argument is NULL",__FUNCTION__); + retvm_if(NULL == now_start_date, false, "\n %s:argument is NULL",__FUNCTION__); + retvm_if(NULL == now_end_date, false, "\n %s:argument is NULL",__FUNCTION__); + if (sch_record->repeat_interval == 0) + { + return FALSE; /* invalid Data */ + } + + /* make valid week array */ + for (i=0;i<7;i++) + { + valid_week[i] = sch_record->week_flag[i]-'0'; + if(valid_week[i]) + { + is_set_week_flag = TRUE; + } + } + + if(is_set_week_flag == FALSE){ + DBG("critical error!! , week flag should be setting "); + return FALSE; + } + + + if (g_cal_cur_id != sch_record->index) + { + if (sch_record->week_start !=0) + { + UINT8 start_week; + + start_week = (UINT8)sch_record->week_start; + is_first_valid_date = TRUE; + + for (i = 0; i < DAY_OF_A_WEEK; i++) + { + if(valid_week[i] == 1) + { + if((is_first_valid_date == TRUE) && (start_week == i)) + { + is_same_start_day_of_week = TRUE; + break; + } + else if(start_week == i) + { + start_day_of_week = start_week; + is_same_start_day_of_week = FALSE; + break; + } + is_first_valid_date = FALSE; + } + } + } + else + { + is_same_start_day_of_week = TRUE; + } + } + + if ( (g_cal_cur_id != sch_record->index) && + + ( !( (__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0 ) + || (__cal_service_compare_date(&(cal_date_param->start_local_date_time),now_end_date) < 0 ) ) ) + ) + { + g_cal_cur_id = sch_record->index; + } + else + { + do + { + int valid_term=1; + count_day = 0; + + week_count = cal_date_param->start_db_date_time.tm_wday; + + // [2010.05.09. Brian] Dangerous statements. + // if weekflag is '0000000', following statement would make process in infinite loop. + while (valid_week[((week_count+valid_term) %7)] ==0 ) + { + valid_term++; + } + + count_day = count_day + valid_term; + + //pass interval week + if (is_same_start_day_of_week == TRUE) + { + if( (week_count+valid_term) >=7 ) + count_day = count_day + ((sch_record->repeat_interval-1) * 7); + } + else + { + if (((week_count+valid_term)%7) == start_day_of_week) + { + count_day = count_day + ((sch_record->repeat_interval-1) * 7); + } + } + + __cal_service_get_day_after_num(&(cal_date_param->start_db_date_time),&(cal_date_param->start_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_db_date_time),&(cal_date_param->end_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->start_local_date_time),&(cal_date_param->start_local_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_local_date_time),&(cal_date_param->end_local_date_time),count_day); + } + while( (__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0)); + + g_cal_cur_id = sch_record->index; + } + + //__cal_service_convert_tm_to_date(&(sch_record->repeat_end_date), &repeat_end_date); + if( (__cal_service_compare_date(&(cal_date_param->repeat_end_date),&(cal_date_param->start_db_date_time)) > 0 ) + || (__cal_service_compare_date(&(cal_date_param->start_local_date_time),now_end_date) < 0 ) ) + { + start_day_of_week = 0; + is_same_start_day_of_week= TRUE; + g_cal_cur_id = -1; + + return FALSE; + } + + return TRUE; + +} + + BOOL +cal_service_get_next_repeat_monthly_valid_date(const cal_sch_full_t *sch_record,cal_date_param_t *cal_date_param,struct tm *now_start_date,struct tm *now_end_date) +{ + UINT32 count_day=0; + int i = 0; + retvm_if(NULL == sch_record, false, "sch_record is NULL"); + retvm_if(NULL == cal_date_param, false, "cal_date_param is NULL"); + retvm_if(NULL == now_start_date, false, "now_start_date is NULL"); + retvm_if(NULL == now_end_date, false, "now_end_date is NULL"); + + if (sch_record->repeat_interval == 0) + { + return FALSE; /* invalid Data */ + } + + if (g_cal_cur_id != sch_record->index) /* SEC 060427 heungjae.jeong last day issue */ + { + cal_date_param->day_for_last_day_event = sch_record->start_date_time.tm_mday; + } + + if ((g_cal_cur_id != sch_record->index) && + ( !( (__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0 ) + || (__cal_service_compare_date(&(cal_date_param->start_local_date_time),now_end_date) < 0 ) ) ) + ) + { + g_cal_cur_id = sch_record->index; + } + else + { + do + { + count_day = 0; + if (sch_record->day_date ==1) + { + int temp=0; + + /* move next month */ + for (i = cal_date_param->start_db_date_time.tm_mon; i < (cal_date_param->start_db_date_time.tm_mon + + sch_record->repeat_interval); i++) + { + temp = temp + month_table[(i)%12] + + (((i%12)==1) ? is_leap_year_tm(cal_date_param->start_db_date_time.tm_year + ((i)/12)) : 0 ) ; + } + + if(cal_date_param->day_for_last_day_event != 0) + { + if (cal_date_param->start_db_date_time.tm_mday > + (month_table[(i)%12]+ ( ((i%12)==1) ? is_leap_year_tm(cal_date_param->start_db_date_time.tm_year + ((i)/12)) : 0 ) ) ) + { + temp = temp - (cal_date_param->day_for_last_day_event- + (month_table[(i)%12]+(((i%12)==1)?is_leap_year_tm(cal_date_param->start_db_date_time.tm_year+((i)/12)):0)) ); + } + else + { + temp = temp + (cal_date_param->day_for_last_day_event-cal_date_param->start_db_date_time.tm_mday); + } + } + + count_day = count_day + temp; + + __cal_service_get_day_after_num(&(cal_date_param->start_db_date_time),&(cal_date_param->start_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_db_date_time),&(cal_date_param->end_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->start_local_date_time),&(cal_date_param->start_local_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_local_date_time),&(cal_date_param->end_local_date_time),count_day); + + } + else /* Relative date check */ + { + int first_day_of_week=0; + struct tm after_from_date; + + after_from_date = cal_date_param->start_db_date_time; + + after_from_date.tm_mon += sch_record->repeat_interval; + + if (after_from_date.tm_mon > 11) + { + after_from_date.tm_year += (after_from_date.tm_mon) / 12; + after_from_date.tm_mon = (after_from_date.tm_mon) % 12; + //after_from_date.tm_mon ++; + } + + if (cal_date_param->repeat_by_set_position == 5) + { + int valid_day_of_week = 0; + int k = 0; + + after_from_date.tm_mday = month_table[after_from_date.tm_mon] + + ( (after_from_date.tm_mon==1) ? is_leap_year_tm(after_from_date.tm_year) : 0 ) ; + + cal_service_set_day_of_week(&after_from_date); + + while(sch_record->start_date_time.tm_wday != valid_day_of_week) + { + valid_day_of_week++; + } /* j = recurrence_day_of_the_week 0..6 */ + + k=0; + while (((k+after_from_date.tm_wday)%7) != valid_day_of_week) + { + k++; + } + + after_from_date.tm_mday = after_from_date.tm_mday - ((7-k)%7); + after_from_date.tm_wday = (after_from_date.tm_wday + k) % 7; + } + else + { + int valid_day_of_week=0; + int k=0; + + after_from_date.tm_mday = 1; + cal_service_set_day_of_week(&after_from_date); + first_day_of_week = after_from_date.tm_wday; + + while(sch_record->start_date_time.tm_wday != valid_day_of_week) + { + valid_day_of_week++; + } /* j = recurrence_day_of_the_week 0..6 */ + + k=0; + while( ((k+first_day_of_week)%7) != valid_day_of_week) + { + k++; + } + + after_from_date.tm_mday = 1 + k; + + after_from_date.tm_mday = after_from_date.tm_mday + (cal_date_param->repeat_by_set_position-1)*7; + cal_service_set_day_of_week(&after_from_date); + } + + count_day = __cal_service_get_num_of_event_day(&(cal_date_param->start_db_date_time),&after_from_date); + + __cal_service_get_day_after_num(&(cal_date_param->start_db_date_time),&(cal_date_param->start_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_db_date_time),&(cal_date_param->end_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->start_local_date_time),&(cal_date_param->start_local_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_local_date_time),&(cal_date_param->end_local_date_time),count_day); + + } + g_cal_cur_id = sch_record->index; + if(count_day == 0) return FALSE; + } + while((__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0)); + } + + //__cal_service_convert_tm_to_date(&(sch_record->repeat_end_date), &repeat_end_date); + if ((__cal_service_compare_date(&(cal_date_param->repeat_end_date),&(cal_date_param->start_db_date_time)) > 0 ) + || (__cal_service_compare_date(&(cal_date_param->start_local_date_time),now_end_date) < 0 )) + { + g_cal_cur_id = -1; + return FALSE; + } + + return TRUE; +} + +BOOL cal_service_get_next_repeat_yearly_valid_date(const cal_sch_full_t *sch_record, + cal_date_param_t *cal_date_param, struct tm *now_start_date, struct tm *now_end_date) +{ + int i; + UINT32 count_day=0; + + retvm_if(NULL == sch_record, FALSE, "sch_record is NULL"); + retvm_if(NULL == cal_date_param, FALSE, "cal_date_param is NULL"); + retvm_if(NULL == now_start_date, FALSE, "now_start_date is NULL"); + retvm_if(NULL == now_end_date, FALSE, "now_end_date is NULL"); + //__cal_service_convert_tm_to_date(&(sch_record->start_date_time), &sch_start_date); + // repeat_by_set_position = (sch_start_date.tm_mday - 1) /7 + 1; + + if (sch_record->repeat_interval== 0) + return FALSE; /* invalid Data */ + + if ((g_cal_cur_id != sch_record->index) && + ( !( (__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0 ) + || (__cal_service_compare_date(&(cal_date_param->start_local_date_time),now_end_date) < 0 ) ) )) + { + g_cal_cur_id = sch_record->index; + } + else + { + do + { + count_day = 0; + + if (sch_record->day_date ==1) + { + int temp = 0; + + for (i = cal_date_param->start_db_date_time.tm_year; i < (cal_date_param->start_db_date_time.tm_year + + sch_record->repeat_interval); i++) + { + temp = temp + 365; + + if(cal_date_param->start_db_date_time.tm_mon > 1) + temp = temp + is_leap_year_tm(i+1); + else + temp = temp + is_leap_year_tm(i); + } + + i = cal_date_param->start_db_date_time.tm_year; + if (cal_date_param->start_db_date_time.tm_mon == 1) + { + // cal_date_param->day_for_last_day_event,i,is_leap_year_tm(i)); + if (cal_date_param->day_for_last_day_event != 0) + { + if (is_leap_year_tm(i+1)) + { + temp = temp + 1; + cal_date_param->day_for_last_day_event = 0; + } + /*if (cal_date_param->start_db_date_time.tm_mday > (month_table[1]+is_leap_year_tm(i)) ) + { + temp = temp - 1; + } + else if (is_leap_year_tm(i)) + { + temp = temp + 1; + }*/ + } + else if (cal_date_param->start_db_date_time.tm_mday == 29 ) + { + temp = temp-1; + cal_date_param->day_for_last_day_event = 29; + // temp, cal_date_param->start_db_date_time.tm_mday,(month_table[1]+is_leap_year_tm(i))); + } + } + + count_day = count_day + temp; + __cal_service_get_day_after_num(&(cal_date_param->start_db_date_time),&(cal_date_param->start_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_db_date_time),&(cal_date_param->end_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->start_local_date_time),&(cal_date_param->start_local_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_local_date_time),&(cal_date_param->end_local_date_time),count_day); + + } + else /* Relative date check */ + { + int first_day_of_week=0; + int temp = 0; + struct tm after_from_date; + + after_from_date = cal_date_param->start_db_date_time; + + for (i=after_from_date.tm_year;i<(after_from_date.tm_year+sch_record->repeat_interval);i++) + { + temp = temp + 365; + + if(after_from_date.tm_mon > 1) + temp = temp + is_leap_year_tm(i+1); + else + temp = temp + is_leap_year_tm(i); + } + + count_day = count_day + temp; + + __cal_service_get_day_after_num(&after_from_date,&after_from_date,count_day); + + if (cal_date_param->repeat_by_set_position == 5) + { + int valid_day_of_week=0; + int k=0; + + after_from_date.tm_mday = month_table[after_from_date.tm_mon] + + ( (after_from_date.tm_mon==1) ? is_leap_year_tm(after_from_date.tm_year) : 0 ) ; + + cal_service_set_day_of_week(&after_from_date); + + while(sch_record->start_date_time.tm_wday != valid_day_of_week) + valid_day_of_week++; /* j = recurrence_day_of_the_week 0..6 */ + + k=0; + while( ((k+after_from_date.tm_wday)%7) != valid_day_of_week) + k++; + + after_from_date.tm_mday = after_from_date.tm_mday - ((7-k)%7); + after_from_date.tm_wday = (after_from_date.tm_wday + k) % 7; + } + else + { + int valid_day_of_week=0; + int k=0; + + after_from_date.tm_mday = 1; + cal_service_set_day_of_week(&after_from_date); + first_day_of_week = after_from_date.tm_wday; + + while(sch_record->start_date_time.tm_wday != valid_day_of_week) + valid_day_of_week++; /* j = recurrence_day_of_the_week 0..6 */ + + k=0; + while( ((k+first_day_of_week)%7) != valid_day_of_week) + k++; + + after_from_date.tm_mday = 1 + k; + + after_from_date.tm_mday = after_from_date.tm_mday + (cal_date_param->repeat_by_set_position-1)*7; + cal_service_set_day_of_week(&after_from_date); + } + + count_day = __cal_service_get_num_of_event_day(&(cal_date_param->start_db_date_time),&after_from_date); + __cal_service_get_day_after_num(&(cal_date_param->start_db_date_time),&(cal_date_param->start_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_db_date_time),&(cal_date_param->end_db_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->start_local_date_time),&(cal_date_param->start_local_date_time),count_day); + __cal_service_get_day_after_num(&(cal_date_param->end_local_date_time),&(cal_date_param->end_local_date_time),count_day); + + } + + g_cal_cur_id = sch_record->index; + } + while((__cal_service_compare_date(&(cal_date_param->end_local_date_time),now_start_date) > 0)); + } + + //__cal_service_convert_tm_to_date(&(sch_record->repeat_end_date), &repeat_end_date); + if((__cal_service_compare_date(&(cal_date_param->repeat_end_date),&(cal_date_param->start_db_date_time)) > 0 ) + ||(__cal_service_compare_date(&(cal_date_param->start_local_date_time),now_end_date) < 0 ) ) + { + g_cal_cur_id = -1; + return FALSE; + } + + return TRUE; +} + + + +int cal_db_service_get_next_valid_exception_time(const cal_sch_full_t *sch_record, + cal_date_param_t *cal_date_param,GList *exception_date_list, + struct tm* start_tm,struct tm* end_tm, + struct tm* next_start_tm,struct tm* next_end_tm) +{ + cal_exception_info_t *exception_info = NULL; + cal_value *cvalue = NULL; + GList *head = NULL; + bool is_exception_date = false; + bool is_valid_date = FALSE; + time_t temp_time = 0; + + retv_if(NULL == sch_record, CAL_ERR_ARG_NULL); + retv_if(NULL == start_tm, CAL_ERR_ARG_NULL); + retv_if(NULL == end_tm, CAL_ERR_ARG_NULL); + retv_if(NULL == next_start_tm, CAL_ERR_ARG_NULL); + retv_if(NULL == next_end_tm, CAL_ERR_ARG_NULL); + + //g_cal_cur_id = -1; + is_valid_date = false; + while (cal_service_get_valid_date_func[sch_record->repeat_term](sch_record, cal_date_param, + start_tm, end_tm) == TRUE ) + { + is_exception_date = false; + //check exception date + if(exception_date_list) + { + // __cal_service_convert_datetime_to_tm(&cal_date_param.start_db_date_time,next_start_tm); + memcpy(next_start_tm,&cal_date_param->start_db_date_time,sizeof(struct tm)); + + //if exception date, calucate again + temp_time = cals_mktime(next_start_tm); + //DBG("next_start_tm [%s\n", ctime(&temp_time)); + + //DBG("exception_date_list = %x\n",exception_date_list); + + head = exception_date_list; + + while(head != NULL) + { + cvalue = head->data; + //DBG("cvalue = %x\n",cvalue); + if(cvalue) + { + exception_info = cvalue->user_data; + temp_time = cals_mktime(&(exception_info->exception_start_time)); + //DBG("exception_start_time [%s\n", ctime(&temp_time)); + + //check exception date is same or not + if( (next_start_tm->tm_year == exception_info->exception_start_time.tm_year) && + (next_start_tm->tm_mon == exception_info->exception_start_time.tm_mon ) && + (next_start_tm->tm_mday == exception_info->exception_start_time.tm_mday) ) + { + is_exception_date = true; + //DBG("is_exception_date = %d\n",is_exception_date); + break; + } + } + else + { + break; + } + head = head->next; + } + + if(is_exception_date) + { + continue; + } + + //printf("is_exception_date = %d",is_exception_date); + cal_set_time_by_dst_info(cal_date_param,sch_record,next_start_tm,next_end_tm); + is_valid_date = true; + break; + } + else + { + cal_set_time_by_dst_info(cal_date_param,sch_record,next_start_tm,next_end_tm); + is_valid_date = true; + break; + } + + } + + if(is_valid_date == true) + { + return CAL_SUCCESS; + } + + return CAL_ERR_FAIL; +} diff --git a/src/cals-recurrence-utils.h b/src/cals-recurrence-utils.h new file mode 100755 index 0000000..64d0eac --- /dev/null +++ b/src/cals-recurrence-utils.h @@ -0,0 +1,173 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef _CALENDAR_SVC_RECURRENCE_UTILS_H_ +#define _CALENDAR_SVC_RECURRENCE_UTILS_H_ + +#ifndef true + #define true 1 + #define false 0 +#endif + +#ifndef TRUE + #define TRUE 1 + #define FALSE 0 +#endif + +#ifndef BOOLEAN + #define BOOLEAN int +#endif + +#ifndef BOOL + #define BOOL int +#endif + + +#ifndef __RECURRENCE_FEATURE__ + #define __RECURRENCE_FEATURE__ + + #define CAL_SUPPORT_TIMEZONE +#ifdef CAL_SUPPORT_TIMEZONE + #define CAL_SUPPORT_AUTO_DST /* precondition: TIMEZONE should be supported */ +#endif + //#define CAL_SUPPORT_EXCEPTION_DATE +#endif + +#define UINT8 unsigned char +#define UINT16 unsigned short +#define UINT32 unsigned long + +#define INT8 signed char +#define INT16 signed short +#define INT32 signed long + + +#define is_leap_year(y) (((y)%4 == 0 && ((y)%100 != 0 || (y)%400 == 0))? 1 : 0) + +typedef struct +{ + UINT8 seconds; // 0 - 59 + UINT8 minutes; // 0 - 59 + UINT8 hours; // 0 - 23 +} +cal_service_time_t; + +//cal_service_date_t : Structure for expressing a calendar date +typedef struct +{ + UINT8 wday; // 0-6, 0=Sunday, 6=Saturday + UINT8 day; // 1 - 28, 29, 30, 31 depending on month and year + UINT8 month; // 1 - 12 + UINT16 year; // Range of 32 years, starting with reference year +}cal_service_date_t; + +//cal_service_time_date_t : Structure for expressing time and date as a single item. +typedef struct +{ + cal_service_time_t time; // Time + cal_service_date_t date; // Date +} +cal_service_time_date_t; + + +#ifdef CAL_SUPPORT_AUTO_DST +typedef enum +{ + DB_STD_LOCAL_STD, /* nothing */ + DB_STD_LOCAL_DST, /* need adjust, after computation */ + DB_INDST_LOCAL_STD, /* need adjust, after computation */ + DB_INDST_LOCAL_DST, /* all datetime +1 hour */ + DB_OUTDST_LOCAL_STD, /* need adjust, after computation */ + DB_OUTDST_LOCAL_DST /* nothing */ + +} cal_dst_type_t; + + +typedef struct +{ + UINT16 tz_index; + UINT8 std_start_month; + UINT8 std_start_position_of_week; + UINT8 std_start_day; + UINT8 std_start_hour; + UINT8 day_start_month; + UINT8 day_start_position_of_week; + UINT8 day_start_day; + UINT8 day_start_hour; +} cal_dst_info_t; +#endif + + +typedef struct +{ + struct tm start_db_date_time; + struct tm end_db_date_time; + struct tm repeat_end_date; + int dbtime_offset; + int db_dst_offset; + + struct tm start_local_date_time; + struct tm end_local_date_time; + + struct tm prev_alarm_time; + UINT32 day_for_last_day_event; + + UINT32 db_time_zone_index; + UINT32 local_time_zone_index; + + int repeat_by_set_position; + GList* exception_date_list; + +#ifdef CAL_SUPPORT_AUTO_DST + struct tm start_db_dst_date_time; + struct tm start_db_std_date_time; + struct tm start_local_dst_date_time; + struct tm start_local_std_date_time; + cal_dst_type_t is_need_adjust_time_for_view; + INT32 i_adjust_time_value; /* 0,-1,+1 viewÇÏ´Â ½ÃÁ¡¿¡ DSTÀû¿ë ¿©ºÎ¿¡ ¸Â°Ô ½Ã°£ Á¶Á¤ÈÄ °ª ¼ÂÆà */ +#endif + +} cal_date_param_t; + +typedef BOOL (*CAL_GET_VALID_DATE_FUNC)(const cal_sch_full_t *,cal_date_param_t *,struct tm *,struct tm *); + +BOOL cal_service_get_next_repeat_none_valid_date(const cal_sch_full_t *sch_record,cal_date_param_t *cal_date_param, + struct tm *now_start_date,struct tm *now_end_date); +BOOL cal_service_get_next_repeat_daily_valid_date(const cal_sch_full_t *sch_record,cal_date_param_t *cal_date_param, + struct tm *now_start_date,struct tm *now_end_date); +BOOL cal_service_get_next_repeat_weekly_valid_date(const cal_sch_full_t *sch_record,cal_date_param_t *cal_date_param, + struct tm *now_start_date,struct tm *now_end_date); +BOOL cal_service_get_next_repeat_monthly_valid_date(const cal_sch_full_t *sch_record,cal_date_param_t *cal_date_param, + struct tm *now_start_date,struct tm *now_end_date); +BOOL cal_service_get_next_repeat_yearly_valid_date(const cal_sch_full_t *sch_record,cal_date_param_t *cal_date_param, + struct tm *now_start_date,struct tm *now_end_date); +void cal_service_set_date_param(cal_date_param_t *cal_date_param,cal_sch_full_t *sch_record); +void cal_service_set_day_of_week(struct tm* date); + +void cal_svc_set_tz_base_info(int year); + +INT8 __cal_service_compare_date(const struct tm *first_date,const struct tm *second_date); + +int cal_db_service_get_next_valid_exception_time(const cal_sch_full_t *sch_record, + cal_date_param_t *cal_date_param,GList *exception_date_list, + struct tm* start_tm,struct tm* end_tm, + struct tm* next_start_tm,struct tm* next_end_tm); + + +#endif /* _CALENDAR_SVC_RECURRENCE_UTILS_H_ */ + diff --git a/src/cals-schedule.c b/src/cals-schedule.c new file mode 100755 index 0000000..32bf7f4 --- /dev/null +++ b/src/cals-schedule.c @@ -0,0 +1,1598 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-sqlite.h" +#include "cals-db-info.h" +#include "cals-db.h" +#include "cals-tz-utils.h" +#include "cals-utils.h" +#include "cals-alarm.h" +#include "cals-schedule.h" + + +static void _cals_adjust_time(cal_sch_full_t *current_record, + time_t *start, time_t *end, time_t *repeat_end) +{ + TMDUMP(current_record->start_date_time); + + if ((current_record->all_day_event == true) && + ((current_record->start_date_time.tm_hour != 0) || + (current_record->start_date_time.tm_min !=0)) ) + { + *start = cals_mktime(&(current_record->start_date_time)); + CALS_DBG("%d",*start); + calendar_svc_util_gmt_to_local(*start, start); + CALS_DBG("%d",*start); + *end = cals_mktime(&(current_record->end_date_time)); + + if(current_record->all_day_event == true && + current_record->end_date_time.tm_hour == 0 && + current_record->end_date_time.tm_min == 0) + *end = *end - 1; + + CALS_DBG("%d",*end); + calendar_svc_util_gmt_to_local(*end, end); + CALS_DBG("%d",*end); + *repeat_end = cals_mktime(&(current_record->repeat_end_date)); + + calendar_svc_util_gmt_to_local(*repeat_end, repeat_end); + } + else + { + *start = cals_mktime(&(current_record->start_date_time)); + *end = cals_mktime(&(current_record->end_date_time)); + *repeat_end = cals_mktime(&(current_record->repeat_end_date)); + } + +} + +static inline int _cals_insert_schedule(cal_sch_full_t *record) +{ + int ret = -1; + char query[CALS_SQL_MAX_LEN] = {0}; + sqlite3_stmt *stmt = NULL; + time_t conv_start_time; + time_t conv_end_time; + time_t conv_repeat_end_time; + time_t conv_last_modified_time; + time_t conv_created_date_time; + time_t conv_completed_date_time; + time_t t = time(NULL); + tzset(); + struct tm * ptm = NULL; + struct tm ttm; + + retv_if(NULL == record, CAL_ERR_ARG_NULL); + + ptm = gmtime_r(&t,&ttm); + retvm_if(NULL == ptm, CAL_ERR_TIME_FAILED, "gmtime_r() Failed(%d)", errno); + + memcpy(&record->last_modified_time, &ttm, sizeof(struct tm)); + + conv_last_modified_time = cals_mktime(&(record->last_modified_time)); + + _cals_adjust_time(record, &conv_start_time, &conv_end_time, &conv_repeat_end_time); + conv_created_date_time = cals_mktime(&(record->created_date_time)); + conv_completed_date_time = cals_mktime(&(record->completed_date_time)); + + ret = snprintf(query, sizeof(query), + "INSERT INTO %s( " + "account_id, type, category, " + "summary, description, location, all_day_event, " + "start_date_time, end_date_time, repeat_item, repeat_interval, " + "repeat_occurrences, repeat_end_date, sun_moon, week_start, " + "week_flag, day_date, last_modified_time, missed, " + "task_status, priority, timezone, file_id, " + "contact_id, busy_status, sensitivity, uid, " + "calendar_type, organizer_name, organizer_email, meeting_status, " + "gcal_id, deleted, updated, location_type, " + "location_summary, etag, calendar_id, sync_status, " + "edit_uri, gevent_id, dst, original_event_id, " + "latitude, longitude, is_deleted, tz_name, " + "tz_city_name, email_id, availability, " + "created_date_time, completed_date_time, progress) " + "VALUES( " + "%d, %d, %d, " + "?, ?, ?, %d, " + "%ld, %ld, %d, %d, " + "%d, %ld, %d, %d, " + "?, %d, %ld, %d, " + "%d, %d, %d, %d, " + "%d, %d, %d, ?, " + "%d, ?, ?, %d, " + "?, %d, ?, %d, " + "?, ?, %d, %d, " + "?, ?, %d, %d, " + "%lf, %lf, %d, ?, " + "?, %d, %d, " + "%ld, %ld, %d)", + CALS_TABLE_SCHEDULE, + record->account_id, record->cal_type, record->sch_category, + record->all_day_event, + conv_start_time, conv_end_time, record->repeat_term, record->repeat_interval, + record->repeat_occurrences, conv_repeat_end_time, record->sun_moon, record->week_start, + record->day_date, (long int)conv_last_modified_time, record->missed, + record->task_status, record->priority, record->timezone, record->file_id, + record->contact_id, record->busy_status, record->sensitivity, + record->calendar_type, record->meeting_status, + record->deleted, record->location_type, + record->calendar_id, record->sync_status, + record->dst, record->original_event_id, + record->latitude, record->longitude, record->is_deleted, + record->email_id, record->availability, + conv_created_date_time, conv_completed_date_time, record->progress); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + int count = 1; + + if (record->summary) + cals_stmt_bind_text(stmt, count, record->summary); + count++; + + if (record->description) + cals_stmt_bind_text(stmt, count, record->description); + count++; + + if (record->location) + cals_stmt_bind_text(stmt, count, record->location); + count++; + + if (record->week_flag) + cals_stmt_bind_text(stmt, count, record->week_flag); + count++; + + if (record->uid) + cals_stmt_bind_text(stmt, count, record->uid); + count++; + + if (record->organizer_name) + cals_stmt_bind_text(stmt, count, record->organizer_name); + count++; + + if (record->organizer_email) + cals_stmt_bind_text(stmt, count, record->organizer_email); + count++; + + if (record->gcal_id) + cals_stmt_bind_text(stmt, count, record->gcal_id); + count++; + + if (record->updated) + cals_stmt_bind_text(stmt, count, record->updated); + count++; + + if (record->location_summary) + cals_stmt_bind_text(stmt, count, record->location_summary); + count++; + + if (record->etag) + cals_stmt_bind_text(stmt, count, record->etag); + count++; + + if (record->edit_uri) + cals_stmt_bind_text(stmt, count, record->edit_uri); + count++; + + if (record->gevent_id) + cals_stmt_bind_text(stmt, count, record->gevent_id); + count++; + + if (record->tz_name) + cals_stmt_bind_text(stmt, count, record->tz_name); + count++; + + if (record->tz_city_name) + cals_stmt_bind_text(stmt, count, record->tz_city_name); + count++; + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("sqlite3_step() Failed(%d)", ret); + return ret; + } + sqlite3_finalize(stmt); + + return cals_last_insert_id(); +} + +int _cals_add_meeting_category_info(const int event_id, const cal_category_info_t *current_record) +{ + int ret; + sqlite3_stmt *stmt; + char sql_value[CALS_SQL_MAX_LEN]; + + retv_if(NULL == current_record, CAL_ERR_ARG_NULL); + + sprintf(sql_value, "INSERT INTO %s(event_id, category_name) " + "VALUES(%d, ?)", CALS_TABLE_MEETING_CATEGORY, event_id); + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + cals_stmt_bind_text(stmt, 1, current_record->category_name); + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("sqlite3_step() Failed(%d)", ret); + return ret; + } + sqlite3_finalize(stmt); + + return CAL_SUCCESS; +} + +static inline int _cals_check_date_validity(struct tm *day) +{ + int month_day_count = 0; + + retvm_if(NULL == day, CAL_FALSE, "day is NULL"); + + month_day_count = cal_db_service_get_day_count_in_month(day->tm_year, day->tm_mon); + + if ((day->tm_mday < 1) || + (day->tm_mday > month_day_count) || + (day->tm_mon < CAL_MONTH_CNT_MIN - 1 ) || + (day->tm_mon > CAL_MONTH_CNT_MAX - 1) || + (day->tm_year < CAL_YEAR_MIN - BENCHMARK_YEAR ) || + (day->tm_year > CAL_YEAR_MAX - BENCHMARK_YEAR)) + { + day->tm_year = 137; + day->tm_mon = 11; + day->tm_mday = 31; + return CAL_TRUE; + } + else + { + return CAL_TRUE; + } +} + +static inline int _cals_sch_check_validity(cal_sch_full_t *sch_record) +{ + struct tm end_date_time = {0}; + struct tm start_date = {0}; + struct tm tmp_start_date_time = {0}; + struct tm tmp_end_date_time = {0}; + + time_t temp_start_time_seconds = 0; + time_t temp_end_time_seconds = 0; + time_t temp_repeat_until_seconds = 0; + + if(sch_record->cal_type != CAL_EVENT_SCHEDULE_TYPE) + return CAL_SUCCESS; + + if((sch_record->repeat_term != CAL_REPEAT_NONE) && + (sch_record->repeat_occurrences) != 0 && + (sch_record->repeat_end_date.tm_year == BASE_TIME_YEAR)) + { + cal_db_service_set_repeat_end_date(sch_record); + } + + if (!_cals_check_date_validity(&sch_record->start_date_time)) + { + //ERR("start_date_time is invalied: %s-%s-%s",sch_record->start_date_time.tm_year, + //sch_record->start_date_time.tm_mon, + //sch_record->start_date_time.tm_mday); + return CAL_ERR_EVENT_START_DATE; + } + + if (!_cals_check_date_validity(&sch_record->end_date_time)) + { + //ERR("end_date_time is invalied: %s-%s-%s",sch_record->end_date_time.tm_year, + // sch_record->end_date_time.tm_mon, + // sch_record->end_date_time.tm_mday); + return CAL_ERR_EVENT_END_DATE; + } + + + if (!_cals_check_date_validity(&sch_record->repeat_end_date)) + { + //ERR("repeat_end_date is invalied: %s-%s-%s",sch_record->repeat_end_date.tm_year, + // sch_record->repeat_end_date.tm_mon, + // sch_record->repeat_end_date.tm_mday); + return CAL_ERR_EVENT_REPEAT_END_DATE; + } + + start_date.tm_year = sch_record->start_date_time.tm_year; + start_date.tm_mon = sch_record->start_date_time.tm_mon; + start_date.tm_mday = sch_record->start_date_time.tm_mday; + + memcpy( &tmp_start_date_time, &sch_record->start_date_time, sizeof(struct tm) ); + memcpy( &tmp_end_date_time, &sch_record->end_date_time, sizeof(struct tm) ); + + temp_start_time_seconds = timegm(&tmp_start_date_time); + temp_end_time_seconds = timegm(&tmp_end_date_time); + temp_repeat_until_seconds = timegm(&sch_record->repeat_end_date); + + if( temp_start_time_seconds > temp_end_time_seconds ) + { + return CAL_ERR_EVENT_DURATION; + } + + switch(sch_record->repeat_term) + { + case CAL_REPEAT_EVERY_DAY: + if( temp_end_time_seconds - temp_start_time_seconds > (sch_record->repeat_interval*ONE_DAY_SECONDS)) + return CAL_ERR_EVENT_REPEAT_DURATION_TOO_SHORT; + break; + /* case CAL_REPEAT_EVERY_WEEKDAYS: + if( temp_end_time_seconds - temp_start_time_seconds > (sch_record->repeat_interval*ONE_DAY_SECONDS)) + { + *error_code = CAL_ERR_EVENT_REPEAT_DURATION_TOO_SHORT; + return false; + } + break; + case CAL_REPEAT_EVERY_WEEKENDS: + if( temp_end_time_seconds - temp_start_time_seconds > (sch_record->repeat_interval*ONE_DAY_SECONDS)) + { + *error_code = CAL_ERR_EVENT_REPEAT_DURATION_TOO_SHORT; + return false; + } + break;*/ + case CAL_REPEAT_EVERY_WEEK: + //if( temp_end_time_seconds - temp_start_time_seconds > (sch_record->repeat_interval*ONE_WEEK_SECONDS)) + //{ + // *error_code = CAL_ERR_EVENT_REPEAT_DURATION_TOO_SHORT; + // return false; + //} + break; + case CAL_REPEAT_EVERY_MONTH: + if( temp_end_time_seconds - temp_start_time_seconds > (sch_record->repeat_interval*ONE_MONTH_SECONDS)) + return CAL_ERR_EVENT_REPEAT_DURATION_TOO_SHORT; + break; + case CAL_REPEAT_EVERY_YEAR: + if( temp_end_time_seconds - temp_start_time_seconds > (sch_record->repeat_interval*ONE_YEAR_SECONDS)) + return CAL_ERR_EVENT_REPEAT_DURATION_TOO_SHORT; + break; + case CAL_REPEAT_NONE: + default: + break; + } + + end_date_time.tm_year = sch_record->repeat_end_date.tm_year; + end_date_time.tm_mon = sch_record->repeat_end_date.tm_mon; + end_date_time.tm_mday = sch_record->repeat_end_date.tm_mday; + end_date_time.tm_hour = sch_record->repeat_end_date.tm_hour; + end_date_time.tm_min = sch_record->repeat_end_date.tm_min; + end_date_time.tm_sec = 59; + + // If Repeat end date is earlier than end date + if ( sch_record->repeat_term != CAL_REPEAT_NONE ) + { + memcpy(&tmp_end_date_time, &sch_record->end_date_time, sizeof(struct tm)); + //if( timegm(&tmp_end_date_time) > timegm(&end_date_time) ) + //{ + // *error_code = CAL_ERR_REPEAT_DURATION; + // return false; + //} + } + return CAL_SUCCESS; +} + + +int cals_insert_schedule(cal_sch_full_t *sch_record) +{ + int ret = 0; + int index = 0; + cal_value *cvalue = NULL; + bool is_success = false; + + retvm_if(NULL == sch_record, CAL_ERR_ARG_INVALID, "sch_record is NULL"); + + ret = _cals_sch_check_validity(sch_record); + retvm_if(CAL_SUCCESS != ret, ret, "_cals_sch_check_validity() is Failed(%d)", ret); + + switch(sch_record->sch_category) + { + case CAL_SCH_NONE: + retvm_if(CAL_EVENT_TODO_TYPE != sch_record->cal_type, CAL_ERR_ARG_INVALID, + "Invalid type(category = %d, component type = %d)", sch_record->sch_category, sch_record->cal_type); + break; + case CAL_SCH_APPOINTMENT: + retvm_if(CAL_EVENT_SCHEDULE_TYPE != sch_record->cal_type, CAL_ERR_ARG_INVALID, + "Invalid type(category = %d, component type = %d)", sch_record->sch_category, sch_record->cal_type); + break; + case CAL_SCH_SPECIAL_OCCASION: + retvm_if(CAL_EVENT_SCHEDULE_TYPE != sch_record->cal_type, CAL_ERR_ARG_INVALID, + "Invalid type(category = %d, component type = %d)", sch_record->sch_category, sch_record->cal_type); + sch_record->all_day_event = 1; + break; + case CAL_SCH_BIRTHDAY: + retvm_if(CAL_EVENT_SCHEDULE_TYPE != sch_record->cal_type, CAL_ERR_ARG_INVALID, + "Invalid type(category = %d, component type = %d)", sch_record->sch_category, sch_record->cal_type); + sch_record->all_day_event = 1; + break; + case CAL_SCH_HOLIDAY: + retvm_if(CAL_EVENT_SCHEDULE_TYPE != sch_record->cal_type, CAL_ERR_ARG_INVALID, + "Invalid type(category = %d, component type = %d)", sch_record->sch_category, sch_record->cal_type); + sch_record->all_day_event = 1; + break; + case CAL_SCH_IMPORTANT: + case CAL_SCH_PRIVATE: + case CAL_SCH_BUSSINESS: + default: + ERR("Invalid type(category = %d, component type = %d)", sch_record->sch_category, sch_record->cal_type); + return CAL_ERR_ARG_INVALID; + } + + sch_record->missed = 0; + + ret = cals_begin_trans(); + retvm_if(ret, ret, "cals_begin_trans() is Failed(%d)", ret); + + ret = _cals_insert_schedule(sch_record); + if(ret < CAL_SUCCESS) { + ERR("_cals_insert_schedule() Failed(%d)", ret); + cals_end_trans(false); + return ret; + } + index = ret; + + if (sch_record->attendee_list) + { + GList *list = g_list_first(sch_record->attendee_list); + cal_participant_info_t *participant_info = NULL; + + while(list) + { + cvalue = list->data; + if(cvalue) + { + participant_info = cvalue->user_data; + if(participant_info->is_deleted==0) + { + ret = cal_service_add_participant_info(index, participant_info); + warn_if(ret, "cal_service_add_participant_info() Failed(%d)", ret); + } + } + list = g_list_next(list); + } + } + + if (sch_record->meeting_category) + { + GList *list = g_list_first(sch_record->meeting_category); + cal_category_info_t *category_info = NULL; + + while(list) + { + cvalue = list->data; + if(cvalue) + { + category_info = cvalue->user_data; + ret = _cals_add_meeting_category_info(index, category_info); + warn_if(CAL_SUCCESS != ret, "_cals_add_meeting_category_info() Failed(%d)", ret); + } + list = g_list_next(list); + } + } + + if (sch_record->exception_date_list) + { + GList *list = g_list_first(sch_record->exception_date_list); + cal_exception_info_t *exception_info = NULL; + + while(list) + { + cvalue = list->data; + if(cvalue) + { + exception_info = cvalue->user_data; + ret = cal_service_add_exception_info(index, exception_info, sch_record); + warn_if(CAL_SUCCESS != ret, "cal_service_add_exception_info() Failed(%d)", ret); + } + list = g_list_next(list); + } + } + + if (sch_record->alarm_list) + { + GList *list = sch_record->alarm_list; + cal_alarm_info_t *alarm_info = NULL; + + while (list) + { + cvalue = list->data; + if (cvalue) + { + alarm_info = cvalue->user_data; + if(alarm_info->is_deleted==0) + { + if (alarm_info->remind_tick != CAL_INVALID_INDEX) + { + ret = cals_alarm_add(index, alarm_info, &sch_record->start_date_time); + warn_if(CAL_SUCCESS != ret, "cals_alarm_add() Failed(%d)", ret); + } + } + } + list = list->next; + } + } + + cals_end_trans(true); + sch_record->index = index; + + if(sch_record->cal_type == CAL_EVENT_SCHEDULE_TYPE) + is_success= cals_notify(CALS_NOTI_TYPE_EVENT); + else + is_success= cals_notify(CALS_NOTI_TYPE_TODO); + warn_if(is_success != true, "cals_notify() Failed"); + + return index; +} + + +static int _cals_delete_meeting_category_info(const int index) +{ + int ret; + char query[CALS_SQL_MIN_LEN]; + + sprintf(query, "DELETE FROM %s WHERE event_id = %d;", CALS_TABLE_MEETING_CATEGORY, index); + + ret = cals_query_exec(query); + retvm_if(CAL_SUCCESS != ret, ret, "cals_query_exec() Failed(%d)", ret); + + return CAL_SUCCESS; +} + + +static int _cals_delete_participant_info(const int index) +{ + int ret; + char query[CALS_SQL_MIN_LEN]; + + sprintf(query, "DELETE FROM %s WHERE event_id = %d", CALS_TABLE_PARTICIPANT, index); + + ret = cals_query_exec(query); + retvm_if(CAL_SUCCESS != ret, ret, "cals_query_exec() Failed(%d)", ret); + + return CAL_SUCCESS; +} + + +static int _cals_delete_recurrency_log(const int event_id) +{ + int ret; + char query[CALS_SQL_MIN_LEN] = {0}; + + sprintf(query, "DELETE FROM %s WHERE event_id = %d", CALS_TABLE_RECURRENCY_LOG, event_id); + + ret = cals_query_exec(query); + retvm_if(CAL_SUCCESS != ret, ret, "cals_query_exec() Failed(%d)", ret); + + return CAL_SUCCESS; +} + + +static inline int _cals_update_schedule(const int index, cal_sch_full_t *current_record) +{ + int ret = -1; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + sqlite3_stmt *stmt = NULL; + time_t conv_start_time; + time_t conv_end_time; + time_t conv_repeat_end_time; + time_t conv_created_date_time; + time_t conv_completed_date_time; + time_t t = time(NULL); + tzset(); + struct tm * ptm = NULL; + struct tm ttm; + + retv_if(NULL == current_record, CAL_ERR_ARG_NULL); + + ptm = gmtime_r(&t, &ttm); + retvm_if(NULL == ptm, CAL_ERR_TIME_FAILED, "gmtime_r() Failed(%d)", errno); + memcpy(¤t_record->last_modified_time, &ttm, sizeof(struct tm)); + + _cals_adjust_time(current_record,&conv_start_time,&conv_end_time,&conv_repeat_end_time); + conv_created_date_time = cals_mktime(&(current_record->created_date_time)); + conv_completed_date_time = cals_mktime(&(current_record->completed_date_time)); + + if (CAL_SYNC_STATUS_UPDATED != current_record->sync_status) + current_record->sync_status = CAL_SYNC_STATUS_UPDATED; + + snprintf(sql_value, sizeof(sql_value), "UPDATE %s set " + "type = %d," + "category = %d," + "summary = ?," + "description = ?," + "location = ?," + "all_day_event = %d," + "start_date_time = %ld," + "end_date_time = %ld," + "repeat_item = %d," + "repeat_interval = %d," + "repeat_occurrences = %d," + "repeat_end_date = %ld," + "sun_moon = %d," + "week_start = %d," + "week_flag = ?," + "day_date = %d," + "last_modified_time = %ld," + "missed = %d," + "task_status = %d," + "priority = %d," + "timezone = %d, " + "file_id = %d, " + "contact_id = %d, " + "busy_status = %d, " + "sensitivity = %d, " + "uid = ?, " + "calendar_type = %d, " + "organizer_name = ?, " + "organizer_email = ?, " + "meeting_status = %d, " + "gcal_id = ?, " + "deleted = %d, " + "updated = ?, " + "location_type = %d, " + "location_summary = ?, " + "etag = ?, " + "calendar_id = %d, " + "sync_status = %d, " + "edit_uri = ?, " + "gevent_id = ?, " + "dst = %d," + "original_event_id = %d," + "latitude = %lf," + "longitude = %lf," + "is_deleted = %d," + "tz_name = ?," + "tz_city_name = ?," + "email_id = %d," + "availability = %d," + "created_date_time = %ld," + "completed_date_time = %ld," + "progress = %d " + "WHERE id = %d;", + CALS_TABLE_SCHEDULE, + current_record->cal_type, + current_record->sch_category, + current_record->all_day_event, + (long int)conv_start_time, + (long int)conv_end_time, + current_record->repeat_term, + current_record->repeat_interval, + current_record->repeat_occurrences, + (long int)conv_repeat_end_time, + current_record->sun_moon, + current_record->week_start, + current_record->day_date, + (long int)cals_mktime(&(current_record->last_modified_time)), + current_record->missed, + current_record->task_status, + current_record->priority, + current_record->timezone, + current_record->file_id, + current_record->contact_id, + current_record->busy_status, + current_record->sensitivity, + current_record->calendar_type, + current_record->meeting_status, + current_record->deleted, + current_record->location_type, + current_record->calendar_id, + current_record->sync_status, + current_record->dst, + current_record->original_event_id, + current_record->latitude, + current_record->longitude, + current_record->is_deleted, + current_record->email_id, + current_record->availability, + (long int)conv_created_date_time, + (long int)conv_completed_date_time, + current_record->progress, + index); + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + int count = 1; + + if (current_record->summary) + cals_stmt_bind_text(stmt, count, current_record->summary); + count++; + + if (current_record->description) + cals_stmt_bind_text(stmt, count, current_record->description); + count++; + + if (current_record->location) + cals_stmt_bind_text(stmt, count, current_record->location); + count++; + + if (current_record->week_flag) + cals_stmt_bind_text(stmt, count, current_record->week_flag); + count++; + + if (current_record->uid) + cals_stmt_bind_text(stmt, count, current_record->uid); + count++; + + if (current_record->organizer_name) + cals_stmt_bind_text(stmt, count, current_record->organizer_name); + count++; + + if (current_record->organizer_email) + cals_stmt_bind_text(stmt, count, current_record->organizer_email); + count++; + + if (current_record->gcal_id) + cals_stmt_bind_text(stmt, count, current_record->gcal_id); + count++; + + if (current_record->updated) + cals_stmt_bind_text(stmt, count, current_record->updated); + count++; + + if (current_record->location_summary) + cals_stmt_bind_text(stmt, count, current_record->location_summary); + count++; + + if (current_record->etag) + cals_stmt_bind_text(stmt, count, current_record->etag); + count++; + + if (current_record->edit_uri) + cals_stmt_bind_text(stmt, count, current_record->edit_uri); + count++; + + if (current_record->gevent_id) + cals_stmt_bind_text(stmt, count, current_record->gevent_id); + count++; + + if (current_record->tz_name) + cals_stmt_bind_text(stmt, count, current_record->tz_name); + count++; + + if (current_record->tz_city_name) + cals_stmt_bind_text(stmt, count, current_record->tz_city_name); + count++; + + ret = cals_stmt_step(stmt); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("sqlite3_step() Failed(%d)", ret); + return ret; + } + sqlite3_finalize(stmt); + + return CAL_SUCCESS; +} + +int cals_update_schedule(const int index, cal_sch_full_t *sch_record) +{ + bool is_success = false; + cal_value * cvalue = NULL; + int ret = 0; + + retv_if(NULL == sch_record, CAL_ERR_ARG_NULL); + + sch_record->missed = 0; + + if((sch_record->repeat_occurrences) != 0 && (sch_record->repeat_end_date.tm_year == BASE_TIME_YEAR)) + { + cal_db_service_set_repeat_end_date(sch_record); + } + + ret = _cals_update_schedule(index, sch_record); + retvm_if(CAL_SUCCESS != ret, ret, "_cals_update_schedule() Failed(%d)", ret); + + _cals_delete_participant_info(index); + if (sch_record->attendee_list) + { + GList *list = g_list_first(sch_record->attendee_list); + cal_participant_info_t* participant_info = NULL; + + while(list) + { + cvalue = (cal_value *)list->data; + participant_info = (cal_participant_info_t*)cvalue->user_data; + + if (0 == participant_info->is_deleted) { + ret = cal_service_add_participant_info(index, participant_info); + warn_if(ret, "cal_service_add_participant_info() Failed(%d)", ret); + } + + list = g_list_next(list); + } + } + + _cals_delete_meeting_category_info(index); + if (sch_record->meeting_category) + { + GList *list = g_list_first(sch_record->meeting_category); + cal_category_info_t* category_info = NULL; + + while (list) + { + cvalue = (cal_value *)list->data; + category_info = (cal_category_info_t*)cvalue->user_data; + ret = _cals_add_meeting_category_info(index,category_info); + warn_if(CAL_SUCCESS != ret, "_cals_add_meeting_category_info() Failed(%d)", ret); + list = g_list_next(list); + } + } + + _cals_delete_recurrency_log(index); + if (sch_record->exception_date_list) + { + GList *list = g_list_first(sch_record->exception_date_list); + cal_exception_info_t* exception_info = NULL; + + while(list) + { + cvalue = (cal_value *)list->data; + if(cvalue) + { + exception_info = (cal_exception_info_t*)cvalue->user_data; + ret = cal_service_add_exception_info(index, exception_info, sch_record); + warn_if(CAL_SUCCESS != ret, "cal_service_add_exception_info() Failed(%d)", ret); + } + list = g_list_next(list); + } + } + + cals_alarm_remove(CALS_ALARM_REMOVE_BY_EVENT_ID, index); + if (sch_record->alarm_list) + { + GList *list = sch_record->alarm_list; + cal_alarm_info_t *alarm_info = NULL; + + while (list) + { + cvalue = (cal_value *)list->data; + alarm_info = (cal_alarm_info_t*)cvalue->user_data; + + if (alarm_info->is_deleted==0) { + if (alarm_info->remind_tick != CAL_INVALID_INDEX) { + ret = cals_alarm_add(index, alarm_info, &sch_record->start_date_time); + warn_if(CAL_SUCCESS != ret, "cals_alarm_add() Failed(%d)", ret); + } + } + + list = g_list_next(list); + } + } + + if(sch_record->cal_type == CAL_EVENT_SCHEDULE_TYPE) + is_success= cals_notify(CALS_NOTI_TYPE_EVENT); + else + is_success= cals_notify(CALS_NOTI_TYPE_TODO); + + return CAL_SUCCESS; +} + + +static inline int _cals_update_recurrency_log(const int exception_event_id) +{ + int ret; + char query[CALS_SQL_MIN_LEN]; + + sprintf(query, "UPDATE %s SET exception_event_id=-1 WHERE exception_event_id=%d", + CALS_TABLE_RECURRENCY_LOG, exception_event_id); + + ret = cals_query_exec(query); + retvm_if(CAL_SUCCESS != ret, ret, "cals_query_exec() Failed(%d)", ret); + + return CAL_SUCCESS; +} + + +int cals_delete_schedule(const int index) +{ + bool is_success = false; + sqlite3_stmt *stmt = NULL; + int ret = 0; + char sql_value[CALS_SQL_MAX_LEN] = {0}; + calendar_type_t type = CAL_PHONE_CALENDAR; + int original_event_id = CAL_INVALID_INDEX; + int repeat_item = 0; + time_t current_time = time(NULL); + int child_index = 0; + int cal_type = 0; + + sprintf(sql_value, "SELECT calendar_type,original_event_id,repeat_item " + "FROM %s WHERE id=%d AND is_deleted = 0", CALS_TABLE_SCHEDULE, index); + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + ret = cals_stmt_step(stmt); + if (CAL_TRUE == ret) { + type = sqlite3_column_int(stmt, 0); + + original_event_id = sqlite3_column_int(stmt, 1); + repeat_item = sqlite3_column_int(stmt, 2); + } else if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("cals_stmt_step() Failed(%d)", ret); + return ret; + } + sqlite3_finalize(stmt); + stmt = NULL; + + if(original_event_id != CAL_INVALID_INDEX) { + _cals_update_recurrency_log(index); + } else if(repeat_item != 0) { + //select child list + sprintf(sql_value, "SELECT id, type FROM %s WHERE original_event_id=%d AND is_deleted = 0", + CALS_TABLE_SCHEDULE, index); + + stmt = cals_query_prepare(sql_value); + retvm_if(NULL == stmt, CAL_ERR_DB_FAILED, "cals_query_prepare() Failed"); + + while (CAL_TRUE == cals_stmt_step(stmt)) + { + child_index =sqlite3_column_int(stmt, 0); + cal_type = sqlite3_column_int(stmt,1); + + memset(sql_value,'\0',CALS_SQL_MAX_LEN); + sprintf(sql_value, "UPDATE %s SET is_deleted = 1,sync_status = %d,last_modified_time = %ld WHERE id = %d", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED, (long int)current_time, child_index); + + ret = cals_query_exec(sql_value); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("cals_query_exec() Failed(%d)", ret); + return ret; + } + + ret = cals_alarm_remove(CALS_ALARM_REMOVE_BY_EVENT_ID, child_index); + if (CAL_SUCCESS != ret) { + sqlite3_finalize(stmt); + ERR("cals_alarm_remove() Failed(%d)", ret); + return ret; + } + } + sqlite3_finalize(stmt); + } + + //delete original event + sprintf(sql_value, "UPDATE %s SET is_deleted = 1,sync_status = %d,last_modified_time = %ld WHERE id = %d;", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED,(long int)current_time, index); + + ret = cals_query_exec(sql_value); + retvm_if(CAL_SUCCESS != ret, ret, "cals_query_exec() Failed(%d)", ret); + + ret = cals_alarm_remove(CALS_ALARM_REMOVE_BY_EVENT_ID, index); + retvm_if(CAL_SUCCESS != ret, ret, "cals_alarm_remove() Failed(%d)", ret); + + _cals_delete_recurrency_log(index); + _cals_delete_participant_info(index); + _cals_delete_meeting_category_info(index); + + if(cal_type == CAL_EVENT_SCHEDULE_TYPE) + is_success= cals_notify(CALS_NOTI_TYPE_EVENT); + else + is_success= cals_notify(CALS_NOTI_TYPE_TODO); + warn_if(is_success != true, , "cals_notify() Failed"); + + return CAL_SUCCESS; +} + + +int cals_rearrage_schedule_field(const char *src, char *dest, int dest_size) +{ + int ret = 0; + if (strstr(src, CAL_VALUE_INT_INDEX)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_INDEX); + + if (strstr(src,CAL_VALUE_INT_ACCOUNT_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_ACCOUNT_ID); + + if (strstr(src,CAL_VALUE_INT_TYPE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_TYPE); + + if (strstr(src,CAL_VALUE_INT_CATEGORY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_CATEGORY); + + if (strstr(src,CAL_VALUE_TXT_SUMMARY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_SUMMARY); + + if (strstr(src,CAL_VALUE_TXT_DESCRIPTION)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_DESCRIPTION); + + if (strstr(src,CAL_VALUE_TXT_LOCATION)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_LOCATION); + + if(strstr(src,CAL_VALUE_INT_ALL_DAY_EVENT)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_ALL_DAY_EVENT); + + if(strstr(src,CAL_VALUE_GMT_START_DATE_TIME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_GMT_START_DATE_TIME); + + if(strstr(src, CAL_VALUE_GMT_END_DATE_TIME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_GMT_END_DATE_TIME); + + if(strstr(src, CAL_VALUE_INT_REPEAT_TERM)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_REPEAT_TERM); + + if(strstr(src, CAL_VALUE_INT_REPEAT_INTERVAL)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_REPEAT_INTERVAL); + + if(strstr(src, CAL_VALUE_INT_REPEAT_OCCURRENCES)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_REPEAT_OCCURRENCES); + + if(strstr(src,CAL_VALUE_GMT_REPEAT_END_DATE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_GMT_REPEAT_END_DATE); + + if(strstr(src,CAL_VALUE_INT_SUN_MOON)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_SUN_MOON); + + if(strstr(src,CAL_VALUE_INT_WEEK_START)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_WEEK_START); + + if(strstr(src,CAL_VALUE_TXT_WEEK_FLAG)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_WEEK_FLAG); + + if(strstr(src,CAL_VALUE_INT_DAY_DATE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_DAY_DATE); + + if(strstr(src,CAL_VALUE_GMT_LAST_MODIFIED_TIME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_GMT_LAST_MODIFIED_TIME); + + if(strstr(src,CAL_VALUE_INT_MISSED)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_MISSED); + + if(strstr(src,CAL_VALUE_INT_TASK_STATUS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_TASK_STATUS); + + if(strstr(src,CAL_VALUE_INT_PRIORITY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_PRIORITY); + + if(strstr(src,CAL_VALUE_INT_TIMEZONE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_TIMEZONE); + + if(strstr(src,CAL_VALUE_INT_FILE_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_FILE_ID); + + if(strstr(src,CAL_VALUE_INT_CONTACT_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_CONTACT_ID); + + if(strstr(src,CAL_VALUE_INT_BUSY_STATUS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_BUSY_STATUS); + + if(strstr(src,CAL_VALUE_INT_SENSITIVITY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_SENSITIVITY); + + if(strstr(src,CAL_VALUE_TXT_UID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_UID); + + if(strstr(src,CAL_VALUE_INT_CALENDAR_TYPE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_CALENDAR_TYPE); + + if(strstr(src,CAL_VALUE_TXT_ORGANIZER_NAME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_ORGANIZER_NAME); + + if(strstr(src,CAL_VALUE_TXT_ORGANIZER_EMAIL)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_ORGANIZER_EMAIL); + + if(strstr(src, CAL_VALUE_INT_MEETING_STATUS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_MEETING_STATUS); + + if(strstr(src,CAL_VALUE_TXT_GCAL_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_GCAL_ID); + + if(strstr(src,CAL_VALUE_INT_DELETED)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_DELETED); + + if(strstr(src,CAL_VALUE_TXT_UPDATED)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_UPDATED); + + if(strstr(src,CAL_VALUE_INT_LOCATION_TYPE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_LOCATION_TYPE); + + if(strstr(src,CAL_VALUE_TXT_LOCATION_SUMMARY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_LOCATION_SUMMARY); + + if(strstr(src,CAL_VALUE_TXT_ETAG)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_ETAG); + + if(strstr(src,CAL_VALUE_INT_CALENDAR_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_CALENDAR_ID); + + if(strstr(src,CAL_VALUE_INT_SYNC_STATUS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_SYNC_STATUS); + + if(strstr(src,CAL_VALUE_TXT_EDIT_URL)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_EDIT_URL); + + if(strstr(src,CAL_VALUE_TXT_GEDERID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_GEDERID); + + if(strstr(src,CAL_VALUE_INT_DST)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_DST); + + if(strstr(src,CAL_VALUE_INT_ORIGINAL_EVENT_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_ORIGINAL_EVENT_ID); + + if(strstr(src,CAL_VALUE_DBL_LATITUDE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_DBL_LATITUDE); + + if(strstr(src,CAL_VALUE_DBL_LONGITUDE)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_DBL_LONGITUDE); + + if(strstr(src,CAL_VALUE_INT_IS_DELETED)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_IS_DELETED); + + if(strstr(src,CAL_VALUE_TXT_TZ_NAME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_TZ_NAME); + + if(strstr(src,CAL_VALUE_TXT_TZ_CITY_NAME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_TXT_TZ_CITY_NAME); + + if(strstr(src,CAL_VALUE_INT_EMAIL_ID)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_EMAIL_ID); + + if(strstr(src,CAL_VALUE_INT_AVAILABILITY)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_AVAILABILITY); + + if(strstr(src,CAL_VALUE_GMT_CREATED_DATE_TIME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_GMT_CREATED_DATE_TIME); + + if(strstr(src,CAL_VALUE_GMT_COMPLETED_DATE_TIME)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_GMT_COMPLETED_DATE_TIME); + + if(strstr(src,CAL_VALUE_INT_PROGRESS)) + ret += snprintf(dest+ret, dest_size-ret, ",%s", CAL_VALUE_INT_PROGRESS); + + return CAL_SUCCESS; +} + +int cals_stmt_get_filted_schedule(sqlite3_stmt *stmt, + cal_sch_full_t *sch_record, const char *select_field) +{ + int count = 0; + int ivalue = 0; + const unsigned char *temp; + const char *start, *result; + + retv_if(NULL == stmt, CAL_ERR_ARG_NULL); + retv_if(NULL == sch_record, CAL_ERR_ARG_NULL); + retv_if(NULL == select_field, CAL_ERR_ARG_NULL); + + start = select_field; + if((result = strstr(start, CAL_VALUE_INT_INDEX))) { + sch_record->index = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_ACCOUNT_ID))) { + sch_record->account_id = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_TYPE))) { + sch_record->cal_type = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_CATEGORY))) { + sch_record->sch_category = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_SUMMARY))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->summary = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_DESCRIPTION))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->description = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_LOCATION))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->location = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_ALL_DAY_EVENT))) { + sch_record->all_day_event = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_GMT_START_DATE_TIME))) { + ivalue = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime((time_t*)&ivalue ),&(sch_record->start_date_time)); + start = result; + } + + if((result = strstr(start, CAL_VALUE_GMT_END_DATE_TIME))) { + ivalue = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime((time_t*)&ivalue),&(sch_record->end_date_time)); + start = result; + } + + if((result = strstr(start, CAL_VALUE_INT_REPEAT_TERM))) { + sch_record->repeat_term = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start, CAL_VALUE_INT_REPEAT_INTERVAL))) { + sch_record->repeat_interval = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start, CAL_VALUE_INT_REPEAT_OCCURRENCES))) { + sch_record->repeat_occurrences = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_GMT_REPEAT_END_DATE))) { + ivalue = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime((time_t*)&ivalue),&(sch_record->repeat_end_date)); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_SUN_MOON))) { + sch_record->sun_moon = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_WEEK_START))) { + sch_record->week_start = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_WEEK_FLAG))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->week_flag = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_DAY_DATE))) { + sch_record->day_date = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_GMT_LAST_MODIFIED_TIME))) { + ivalue = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime((time_t*)&ivalue),&(sch_record->last_modified_time)); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_MISSED))) { + sch_record->missed = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_TASK_STATUS))) { + sch_record->task_status = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_PRIORITY))) { + sch_record->priority = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_TIMEZONE))) { + sch_record->timezone = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_FILE_ID))) { + sch_record->file_id = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_CONTACT_ID))) { + sch_record->contact_id = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_BUSY_STATUS))) { + sch_record->busy_status = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_SENSITIVITY))) { + sch_record->sensitivity = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_UID))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->uid = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_CALENDAR_TYPE))) { + sch_record->calendar_type = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_CALENDAR_TYPE))) { + sch_record->calendar_type = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_ORGANIZER_NAME))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->organizer_name = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_ORGANIZER_EMAIL))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->organizer_email = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start, CAL_VALUE_INT_MEETING_STATUS))) { + sch_record->meeting_status = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_GCAL_ID))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->gcal_id = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_DELETED))) { + sch_record->deleted = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_UPDATED))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->updated = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_LOCATION_TYPE))) { + sch_record->location_type = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_LOCATION_SUMMARY))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->location_summary = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_ETAG))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->etag = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_CALENDAR_ID))) { + sch_record->calendar_id = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_SYNC_STATUS))) { + sch_record->sync_status = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_EDIT_URL))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->edit_uri = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_GEDERID))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->gevent_id = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_DST))) { + sch_record->dst = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_ORIGINAL_EVENT_ID))) { + sch_record->original_event_id = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_DBL_LATITUDE))) { + sch_record->latitude = sqlite3_column_double(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_DBL_LONGITUDE))) { + sch_record->longitude = sqlite3_column_double(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_IS_DELETED))) { + sch_record->is_deleted = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_TZ_NAME))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->tz_name = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_TXT_TZ_CITY_NAME))) { + temp = sqlite3_column_text(stmt, count++); + sch_record->tz_city_name = SAFE_STRDUP(temp); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_EMAIL_ID))) { + sch_record->email_id = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_AVAILABILITY))) { + sch_record->availability = sqlite3_column_int(stmt, count++); + start = result; + } + + if((result = strstr(start,CAL_VALUE_GMT_CREATED_DATE_TIME))) { + ivalue = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime((time_t*)&ivalue ),&(sch_record->created_date_time)); + start = result; + } + + if((result = strstr(start,CAL_VALUE_GMT_COMPLETED_DATE_TIME))) { + ivalue = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime((time_t*)&ivalue ),&(sch_record->completed_date_time)); + start = result; + } + + if((result = strstr(start,CAL_VALUE_INT_PROGRESS))) { + sch_record->progress = sqlite3_column_int(stmt, count++); + start = result; + } + + + return CAL_SUCCESS; +} + + +void cals_stmt_get_full_schedule(sqlite3_stmt *stmt,cal_sch_full_t *sch_record, bool is_utc) +{ + int count = 0; + long int tmp_time = 0; + const unsigned char *temp; + + sch_record->index = sqlite3_column_int(stmt, count++); + sch_record->account_id = sqlite3_column_int(stmt, count++); + sch_record->cal_type = sqlite3_column_int(stmt, count++); + sch_record->sch_category = sqlite3_column_int(stmt, count++); + temp = sqlite3_column_text(stmt, count++); + sch_record->summary = SAFE_STRDUP(temp); + temp = sqlite3_column_text(stmt, count++); + sch_record->description = SAFE_STRDUP(temp); + temp = sqlite3_column_text(stmt, count++); + sch_record->location = SAFE_STRDUP(temp); + sch_record->all_day_event = sqlite3_column_int(stmt, count++); + + tmp_time = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&tmp_time),&(sch_record->start_date_time)); + + tmp_time = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&tmp_time),&(sch_record->end_date_time)); + + sch_record->repeat_term = sqlite3_column_int(stmt, count++); + sch_record->repeat_interval = sqlite3_column_int(stmt, count++); + sch_record->repeat_occurrences = sqlite3_column_int(stmt, count++); + + tmp_time = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&tmp_time),&(sch_record->repeat_end_date)); + + sch_record->sun_moon = sqlite3_column_int(stmt, count++); + sch_record->week_start = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + sch_record->week_flag = SAFE_STRDUP(temp); + + sch_record->day_date = sqlite3_column_int(stmt, count++); + + tmp_time = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&tmp_time), &(sch_record->last_modified_time)); + + sch_record->missed = sqlite3_column_int(stmt, count++); + sch_record->task_status = sqlite3_column_int(stmt, count++); + sch_record->priority = sqlite3_column_int(stmt, count++); + sch_record->timezone = sqlite3_column_int(stmt, count++); + sch_record->file_id = sqlite3_column_int(stmt, count++); + sch_record->contact_id = sqlite3_column_int(stmt, count++); + sch_record->busy_status = sqlite3_column_int(stmt, count++); + sch_record->sensitivity = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + sch_record->uid = SAFE_STRDUP(temp); + + sch_record->calendar_type = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + sch_record->organizer_name = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + sch_record->organizer_email = SAFE_STRDUP(temp); + + sch_record->meeting_status = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + sch_record->gcal_id = SAFE_STRDUP(temp); + + sch_record->deleted = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + sch_record->updated = SAFE_STRDUP(temp); + + sch_record->location_type = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + sch_record->location_summary = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + sch_record->etag = SAFE_STRDUP(temp); + + sch_record->calendar_id = sqlite3_column_int(stmt, count++); + + sch_record->sync_status = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + sch_record->edit_uri = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + sch_record->gevent_id = SAFE_STRDUP(temp); + + sch_record->dst = sqlite3_column_int(stmt, count++); + + sch_record->original_event_id = sqlite3_column_int(stmt, count++); + + sch_record->latitude = sqlite3_column_double(stmt,count++); + sch_record->longitude = sqlite3_column_double(stmt,count++); + sch_record->deleted = sqlite3_column_int(stmt, count++); + + temp = sqlite3_column_text(stmt, count++); + sch_record->tz_name = SAFE_STRDUP(temp); + + temp = sqlite3_column_text(stmt, count++); + sch_record->tz_city_name = SAFE_STRDUP(temp); + + sch_record->email_id = sqlite3_column_int(stmt, count++); + + sch_record->availability = sqlite3_column_int(stmt, count++); + + tmp_time = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&tmp_time),&(sch_record->created_date_time)); + + tmp_time = sqlite3_column_int(stmt, count++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&tmp_time),&(sch_record->completed_date_time)); + + sch_record->progress = sqlite3_column_int(stmt,count++); +} + diff --git a/src/cals-schedule.h b/src/cals-schedule.h new file mode 100755 index 0000000..9e2b9a0 --- /dev/null +++ b/src/cals-schedule.h @@ -0,0 +1,42 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_SCHEDULE_H__ +#define __CALENDAR_SVC_SCHEDULE_H__ + +/** + * This function add full field of calendar info to DB. + * + * @return This function returns true on success, or false on failure. + * @param[in] sch_record Points of the full field information for schedule table' s record. + * @exception CAL_ERR_DB_FAILED, CAL_ERR_ARG_INVALID, CAL_ERR_DB_NOT_OPENED, + * CAL_ERR_DB_RECORD_NOT_FOUND, CAL_ERR_DB_FAILED + */ +int cals_insert_schedule(cal_sch_full_t *sch_record); +int cals_update_schedule(const int index, cal_sch_full_t *sch_record); +int cals_delete_schedule(const int index); + +int cals_rearrage_schedule_field(const char *src, char *dest, int dest_size); + +int cals_stmt_get_filted_schedule(sqlite3_stmt *stmt,cal_sch_full_t *sch_record, const char *select_field); +void cals_stmt_get_full_schedule(sqlite3_stmt *stmt,cal_sch_full_t *sch_record, bool is_utc); + + +#endif /* __CALENDAR_SVC_SCHEDULE_H__ */ + + diff --git a/src/cals-sqlite.c b/src/cals-sqlite.c new file mode 100755 index 0000000..b25361e --- /dev/null +++ b/src/cals-sqlite.c @@ -0,0 +1,157 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-db-info.h" +#include "cals-sqlite.h" + +sqlite3 *calendar_db_handle; + +int cals_db_open(void) +{ + int ret; + + if (!calendar_db_handle) { + ret = db_util_open(CALS_DB_PATH, &calendar_db_handle, 0); + retvm_if(SQLITE_OK != ret, CAL_ERR_DB_NOT_OPENED, + "db_util_open() Failed(%d).", ret); + } + return CAL_SUCCESS; +} + +int cals_db_close(void) +{ + int ret = 0; + + if (calendar_db_handle) { + ret = db_util_close(calendar_db_handle); + warn_if(SQLITE_OK != ret, "db_util_close() Failed(%d)", ret); + calendar_db_handle = NULL; + CALS_DBG("The database disconnected really."); + } + + return CAL_SUCCESS; +} + +int cals_last_insert_id(void) +{ + return sqlite3_last_insert_rowid(calendar_db_handle); +} + +int cals_query_get_first_int_result(const char *query) +{ + int ret; + sqlite3_stmt *stmt = NULL; + retvm_if(NULL == calendar_db_handle, CAL_ERR_DB_NOT_OPENED, "Database is not opended"); + + ret = sqlite3_prepare_v2(calendar_db_handle, query, strlen(query), &stmt, NULL); + retvm_if(SQLITE_OK != ret, CAL_ERR_DB_FAILED, + "sqlite3_prepare_v2(%s) failed(%s).", query, sqlite3_errmsg(calendar_db_handle)); + + ret = sqlite3_step(stmt); + if (SQLITE_ROW != ret) { + ERR("sqlite3_step() failed(%d, %s).", ret, sqlite3_errmsg(calendar_db_handle)); + sqlite3_finalize(stmt); + if (SQLITE_DONE == ret) return CAL_ERR_DB_RECORD_NOT_FOUND; + return CAL_ERR_DB_FAILED; + } + + ret = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + + return ret; +} + + +int cals_query_exec(char *query) +{ + int ret; + char *err_msg = NULL; + + retvm_if(NULL == calendar_db_handle, CAL_ERR_DB_NOT_OPENED, "Database is not opended"); + //CALS_DBG("query : %s", query); + + ret = sqlite3_exec(calendar_db_handle, query, NULL, NULL, &err_msg); + if (SQLITE_OK != ret) { + ERR("sqlite3_exec(%s) failed(%d, %s).", query, ret, err_msg); + sqlite3_free(err_msg); + switch (ret) { + case SQLITE_BUSY: + case SQLITE_LOCKED: + return CAL_ERR_DB_LOCK; + case SQLITE_IOERR: + return CAL_ERR_IO_ERR; + case SQLITE_FULL: + return CAL_ERR_NO_SPACE; + default: + return CAL_ERR_DB_FAILED; + } + } + + return CAL_SUCCESS; +} + +sqlite3_stmt* cals_query_prepare(char *query) +{ + int ret = -1; + sqlite3_stmt *stmt = NULL; + + retvm_if(NULL == calendar_db_handle, NULL, "Database is not opended"); + //CALS_DBG("prepare query : %s", query); + + ret = sqlite3_prepare_v2(calendar_db_handle, query, strlen(query), &stmt, NULL); + retvm_if(SQLITE_OK != ret, NULL, + "sqlite3_prepare_v2(%s) Failed(%s).", query, sqlite3_errmsg(calendar_db_handle)); + + return stmt; +} + +int cals_stmt_step(sqlite3_stmt *stmt) +{ + int ret; + ret = sqlite3_step(stmt); + switch (ret) { + case SQLITE_BUSY: + case SQLITE_LOCKED: + ret = CAL_ERR_DB_LOCK; + break; + case SQLITE_IOERR: + ret = CAL_ERR_IO_ERR; + break; + case SQLITE_FULL: + ret = CAL_ERR_NO_SPACE; + break; + case SQLITE_CONSTRAINT: + ret = CAL_ERR_ALREADY_EXIST; + break; + case SQLITE_ROW: + ret = CAL_TRUE; + break; + case SQLITE_DONE: + ret = CAL_SUCCESS; + break; + default: + ERR("sqlite3_step() Failed(%d)", ret); + ret = CAL_ERR_DB_FAILED; + break; + } + return ret; +} diff --git a/src/cals-sqlite.h b/src/cals-sqlite.h new file mode 100755 index 0000000..7cbe022 --- /dev/null +++ b/src/cals-sqlite.h @@ -0,0 +1,42 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_SQLITE_H__ +#define __CALENDAR_SVC_SQLITE_H__ + +#include + +#define CALS_SQL_MAX_LEN 2048 +#define CALS_SQL_MIN_LEN 1024 + +int cals_db_open(void); +int cals_db_close(void); + +int cals_last_insert_id(void); + +int cals_query_get_first_int_result(const char *query); +int cals_query_exec(char *query); + +sqlite3_stmt* cals_query_prepare(char *query); +int cals_stmt_step(sqlite3_stmt *stmt); + +static inline int cals_stmt_bind_text(sqlite3_stmt *stmt, int pos, const char *str) { + return sqlite3_bind_text(stmt, pos, str, strlen(str), SQLITE_STATIC); +} + +#endif /* __CALENDAR_SVC_SQLITE_H__ */ diff --git a/src/cals-struct.c b/src/cals-struct.c new file mode 100755 index 0000000..5866bde --- /dev/null +++ b/src/cals-struct.c @@ -0,0 +1,2639 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include + +#include "calendar-svc-provider.h" +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-tz-utils.h" +#include "cals-db.h" +#include "cals-utils.h" + +int cals_init_full_record(cal_sch_full_t *sch_full_record) +{ + time_t t = time(NULL); + tzset(); + struct tm * cur_time = NULL;//localtime(&t); + struct tm ttm; + + cur_time = localtime_r(&t,&ttm); + if(NULL == cur_time) + { + return CAL_ERR_FAIL; + } + struct tm temp_date_time = {0}; + struct tm current_time = {0}; + + retvm_if(NULL == sch_full_record, CAL_ERR_ARG_INVALID , "sch_full_record is NULL"); + + memset(sch_full_record,0,sizeof(cal_sch_full_t)); + + sch_full_record->cal_type = CAL_EVENT_SCHEDULE_TYPE; + sch_full_record->sch_category = CAL_SCH_APPOINTMENT; + memset(&temp_date_time, 0 ,sizeof(struct tm)); + memset(&sch_full_record->start_date_time, 0 ,sizeof(struct tm)); + memset(&sch_full_record->end_date_time, 0 ,sizeof(struct tm)); + memset(&sch_full_record->repeat_end_date, 0 ,sizeof(struct tm)); + memset(&sch_full_record->last_modified_time, 0 ,sizeof(struct tm)); + memset(&sch_full_record->created_date_time, 0 ,sizeof(struct tm)); + memset(&sch_full_record->completed_date_time, 0 ,sizeof(struct tm)); + memcpy(¤t_time,cur_time,sizeof(struct tm)); + + memcpy(&sch_full_record->start_date_time,¤t_time,sizeof(struct tm)); + memcpy(&sch_full_record->end_date_time,¤t_time,sizeof(struct tm)); + sch_full_record->start_date_time.tm_sec = 0; + sch_full_record->end_date_time.tm_sec = 0; + sch_full_record->end_date_time.tm_hour ++; + if (sch_full_record->end_date_time.tm_hour > 23) + { + sch_full_record->end_date_time.tm_hour = 0; + cal_db_service_get_tomorrow(&sch_full_record->end_date_time); + } + + cal_db_service_get_next_month(&sch_full_record->repeat_end_date); + temp_date_time.tm_year = TM_YEAR_MIN; + temp_date_time.tm_mon = MONTH_MIN; + temp_date_time.tm_mday = MONTH_DAY_MIN; + memcpy(&sch_full_record->repeat_end_date,&temp_date_time,sizeof(struct tm)); + memcpy(&sch_full_record->last_modified_time,&temp_date_time,sizeof(struct tm)); + memcpy(&sch_full_record->created_date_time,&temp_date_time,sizeof(struct tm)); + memcpy(&sch_full_record->completed_date_time,&temp_date_time,sizeof(struct tm)); + + sch_full_record->index = CAL_INVALID_INDEX; + sch_full_record->repeat_term = CAL_REPEAT_NONE; + sch_full_record->day_date = 1; + sch_full_record->timezone = -1; + sch_full_record->contact_id = CAL_INVALID_INDEX; + sch_full_record->calendar_type = CAL_PHONE_CALENDAR; + sch_full_record->calendar_id = CAL_INVALID_INDEX; + sch_full_record->attendee_list = NULL; + sch_full_record->meeting_category = NULL; + sch_full_record->busy_status = 2; + sch_full_record->summary = NULL; + sch_full_record->description = NULL; + sch_full_record->location= NULL; + sch_full_record->organizer_email = NULL; + sch_full_record->organizer_name = NULL; + sch_full_record->uid= NULL; + sch_full_record->gcal_id = NULL; + sch_full_record->location_summary = NULL; + sch_full_record->etag = NULL; + sch_full_record->edit_uri = NULL; + sch_full_record->gevent_id = NULL; + sch_full_record->tz_name = NULL; + sch_full_record->tz_city_name = NULL; + sch_full_record->original_event_id = CAL_INVALID_INDEX; + + // TODO : To define default value. + sch_full_record->sync_status = CAL_SYNC_STATUS_NEW; + sch_full_record->timezone = CAL_TIME_ZONE_GMT_L11; + sch_full_record->is_deleted = 0; + sch_full_record->account_id = -1; + sch_full_record->calendar_id = DEFAULT_CALENDAR_ID; + + return CAL_SUCCESS; +} + +static inline void cals_init_calendar_record(calendar_t *calendar) +{ + calendar->index = -1; + calendar->visibility = true; + calendar->account_id = LOCAL_ACCOUNT_ID; +} + +API cal_struct* calendar_svc_struct_new(const char *event_type) +{ + int ret, type; + void *user_data; + cal_struct *temp; + + retvm_if(NULL == event_type, NULL, "event_type is NULL"); + + if(0 == strcmp(event_type, CAL_STRUCT_SCHEDULE)) { + type = CAL_STRUCT_TYPE_SCHEDULE; + + user_data = (cal_sch_full_t*)malloc(sizeof(cal_sch_full_t)); + retvm_if(NULL == user_data, NULL, "malloc(cal_sch_full_t:sch) Failed(%d)", errno); + + ret = cals_init_full_record(user_data); + if(ret) { + free(user_data); + ERR("cals_init_full_record() Failed(%d)", ret); + return NULL; + } + } else if (0 == strcmp(event_type, CAL_STRUCT_TODO)) { + type = CAL_STRUCT_TYPE_TODO; + + user_data = (cal_sch_full_t*)malloc(sizeof(cal_sch_full_t)); + retvm_if(NULL == user_data, NULL, "malloc(cal_sch_full_t:todo) Failed(%d)", errno); + + ret = cals_init_full_record(user_data); + if(ret) { + free(user_data); + ERR("cals_init_full_record() Failed(%d)", ret); + return NULL; + } + + ((cal_sch_full_t*)user_data)->cal_type = CAL_EVENT_TODO_TYPE; + ((cal_sch_full_t*)user_data)->end_date_time.tm_year = 69; + ((cal_sch_full_t*)user_data)->sch_category = CAL_SCH_NONE; + } else if (0 == strcmp(event_type, CAL_STRUCT_CALENDAR)) { + type = CAL_STRUCT_TYPE_CALENDAR; + + user_data = calloc(1, sizeof(calendar_t)); + retvm_if(NULL == user_data, NULL, "calloc(calendar_t) Failed(%d)", errno); + + cals_init_calendar_record(user_data); + } else if (0 == strcmp(event_type, CAL_STRUCT_TIMEZONE)) { + type = CAL_STRUCT_TYPE_TIMEZONE; + + user_data = (cal_timezone_t*)calloc(1, sizeof(cal_timezone_t)); + retvm_if(NULL == user_data, NULL, "calloc(cal_timezone_t) Failed(%d)", errno); + } else { + ERR("Unknown type(%s)", event_type); + return NULL; + } + + temp = (cal_struct*)calloc(1, sizeof(cal_struct)); + if(NULL == temp) { + free(user_data); + ERR("calloc(cal_struct) Failed(%d)", errno); + return NULL; + } + temp->event_type = type; + temp->user_data = user_data; + + return temp; +} + +//API to free the calendar struct +static inline void cals_free_calendar_record(calendar_t *calendar) +{ + retm_if(calendar == NULL, "calendar is NULL"); + + free(calendar->calendar_id); + free(calendar->uid); + free(calendar->link); + free(calendar->name); + free(calendar->description); + free(calendar->author); + free(calendar->color); + free(calendar->location); + free(calendar->timezone_label); + free(calendar->user_location); + free(calendar->weather); + + free(calendar); +} + +static inline void cals_free_timezone_record(cal_timezone_t *tz_info) +{ + retm_if(NULL == tz_info, "tz_info is NULL"); + + free(tz_info->standard_name); + free(tz_info->day_light_name); + + free(tz_info); +} + +API int calendar_svc_struct_free (cal_struct** event) +{ + int ret = 0; + + retvm_if(NULL == event || NULL == *event, CAL_ERR_ARG_INVALID, "Invalid parameter"); + + switch((*event)->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + cal_db_service_free_full_record((cal_sch_full_t*)(*event)->user_data,&ret); + CAL_FREE((*event)->user_data); + CAL_FREE(*event); + break; + case CAL_STRUCT_TYPE_CALENDAR: + cals_free_calendar_record((calendar_t*)(*event)->user_data); + CAL_FREE(*event); + break; + case CAL_STRUCT_TYPE_TIMEZONE: + cals_free_timezone_record((cal_timezone_t*)(*event)->user_data); + CAL_FREE(*event); + break; + default: + ERR("Unknown type(%d)", (*event)->event_type); + break; + } + + return CAL_SUCCESS; +} + +API char * calendar_svc_struct_get_str (cal_struct *event,const char *field) +{ + //CALS_FN_CALL(); + retvm_if(NULL == event || NULL == event->user_data || NULL == field, + NULL,"Invalid parameters."); + + cal_sch_full_t * sch_rec = NULL; + calendar_t * cal_rec = NULL; + cal_timezone_t *tz_rec = NULL; + + switch(event->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + sch_rec = (cal_sch_full_t*)event->user_data; + if(0 == strcmp(field,CAL_VALUE_TXT_SUMMARY)) + { + return (sch_rec->summary); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_DESCRIPTION)) + { + return (sch_rec->description); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_LOCATION)) + { + return (sch_rec->location); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_WEEK_FLAG)) + { + return (sch_rec->week_flag); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_UID)) + { + return (sch_rec->uid); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ORGANIZER_NAME)) + { + return (sch_rec->organizer_name); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ORGANIZER_EMAIL)) + { + return (sch_rec->organizer_email); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_GCAL_ID)) + { + return (sch_rec->gcal_id); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_UPDATED)) + { + return (sch_rec->updated); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_LOCATION_SUMMARY)) + { + return (sch_rec->location_summary); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ETAG)) + { + return (sch_rec->etag); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_EDIT_URL)) + { + return (sch_rec->edit_uri); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_GEDERID)) + { + return (sch_rec->gevent_id); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_TZ_NAME)) + { + return (sch_rec->tz_name); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_TZ_CITY_NAME)) + { + return (sch_rec->tz_city_name); + } + else + { + ERR("Can not find the field(%s)!", field); + return NULL; + } + break; + + case CAL_STRUCT_TYPE_CALENDAR: + cal_rec = (calendar_t*)event->user_data; + if(0 == strcmp(field,CAL_TABLE_TXT_CALENDAR_ID)) + { + return(cal_rec->calendar_id); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_UID)) + { + return(cal_rec->uid); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_LINK)) + { + return(cal_rec->link); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_NAME)) + { + return(cal_rec->name); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_DESCRIPTION)) + { + return(cal_rec->description); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_AUTHOR)) + { + return(cal_rec->author); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_COLOR)) + { + return(cal_rec->color); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_LOCATION)) + { + return(cal_rec->location); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_TIME_ZONE_LABEL)) + { + return(cal_rec->timezone_label); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_USER_LOCATION)) + { + return(cal_rec->user_location); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_WEATHER)) + { + return(cal_rec->weather); + } + else + { + ERR("Can not find the field!(%s)",field); + return NULL; + } + + break; + case CAL_STRUCT_TYPE_TIMEZONE: + tz_rec = (cal_timezone_t*)event->user_data; + if(0 == strcmp(field,CAL_TZ_VALUE_TXT_STD_NAME)) + { + return(tz_rec->standard_name); + } + else if(0 == strcmp(field,CAL_TZ_VALUE_TXT_DST_NAME)) + { + return(tz_rec->day_light_name); + }else { + ERR("Can not find the field!(%s)",field); + return NULL; + } + + break; + default: + ERR("Can not find the field!(%s)!", field); + return NULL; + } +} + +API int calendar_svc_struct_get_int(cal_struct *event, const char *field) +{ + cal_sch_full_t * sch_rec = NULL; + calendar_t * cal_rec = NULL; + cal_timezone_t *tz_rec = NULL; + + retvm_if(NULL == event || NULL==event->user_data || NULL == field, 0, + "Invalid parameters(event(%p), field(%p))", event, field); + + switch(event->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + sch_rec = event->user_data; + if(0 == strcmp(field,CAL_VALUE_INT_INDEX)) + { + return sch_rec->index; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ACCOUNT_ID)) + { + return sch_rec->account_id; + } + else if(0 == strcmp(field, CAL_VALUE_INT_TYPE)) + { + return sch_rec->cal_type; + } + else if(0 == strcmp(field, CAL_VALUE_INT_CATEGORY)) + { + return sch_rec->sch_category; + } + else if(0 == strcmp(field,CAL_VALUE_INT_REPEAT_TERM)) + { + return sch_rec->repeat_term; + } + else if(0 == strcmp(field,CAL_VALUE_INT_REPEAT_INTERVAL)) + { + return sch_rec->repeat_interval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_REPEAT_OCCURRENCES)) + { + return sch_rec->repeat_occurrences; + } + else if(0 == strcmp(field,CAL_VALUE_INT_DAY_DATE)) + { + return sch_rec->day_date; + } + else if(0 == strcmp(field,CAL_VALUE_INT_FILE_ID)) + { + return sch_rec->file_id; + } + else if(0 == strcmp(field,CAL_VALUE_INT_CONTACT_ID)) + { + return sch_rec->contact_id; + } + else if(0 == strcmp(field,CAL_VALUE_INT_BUSY_STATUS)) + { + return sch_rec->busy_status; + } + else if(0 == strcmp(field,CAL_VALUE_INT_SENSITIVITY)) + { + return sch_rec->sensitivity; + } + else if(0 == strcmp(field, CAL_VALUE_INT_CALENDAR_TYPE)) + { + return sch_rec->calendar_type; + } + else if(0 == strcmp(field,CAL_VALUE_INT_MEETING_STATUS)) + { + return sch_rec->meeting_status; + } + else if(0 == strcmp(field,CAL_VALUE_INT_LOCATION_TYPE)) + { + return sch_rec->location_type; + } + else if(0 == strcmp(field,CAL_VALUE_INT_CALENDAR_ID)) + { + return sch_rec->calendar_id; + } + else if(0 == strcmp(field,CAL_VALUE_INT_DST)) + { + return sch_rec->dst; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ORIGINAL_EVENT_ID)) + { + return sch_rec->original_event_id; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ALL_DAY_EVENT)) + { + return sch_rec->all_day_event; + } + else if(0 == strcmp(field,CAL_VALUE_INT_SYNC_STATUS)) + { + return sch_rec->sync_status; + } + else if(0 == strcmp(field,CAL_VALUE_INT_SUN_MOON)) + { + return sch_rec->sun_moon; + } + else if(0 == strcmp(field,CAL_VALUE_INT_PRIORITY)) + { + return sch_rec->priority; + } + else if(0 == strcmp(field,CAL_VALUE_INT_WEEK_START)) + { + return sch_rec->week_start; + } + else if(0 == strcmp(field,CAL_VALUE_INT_TASK_STATUS)) + { + return sch_rec->task_status; + } + else if(0 == strcmp(field,CAL_VALUE_INT_TIMEZONE)) + { + return sch_rec->timezone; + } + else if(0 == strcmp(field,CAL_VALUE_INT_EMAIL_ID)) + { + return sch_rec->email_id; + } + else if(0 == strcmp(field,CAL_VALUE_INT_AVAILABILITY)) + { + return sch_rec->availability; + } + else if(0 == strcmp(field,CAL_VALUE_INT_DELETED)) + { + return sch_rec->deleted; + } + else if(0 == strcmp(field,CAL_VALUE_INT_PROGRESS)) + { + return sch_rec->progress; + } + else + { + ERR("Can not find the field(%s)",field); + } + break; + case CAL_STRUCT_TYPE_CALENDAR: + cal_rec = event->user_data; + + if(0 == strcmp(field,CAL_TABLE_INT_INDEX)) + { + return cal_rec->index; + } + else if(0 == strcmp(field,CAL_TABLE_INT_UPDATED)) + { + return cal_rec->updated; + } + else if(0 == strcmp(field,CAL_TABLE_INT_HIDDEN)) + { + return cal_rec->hidden; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SELECTED)) + { + return cal_rec->selected; + } + else if(0 == strcmp(field,CAL_TABLE_INT_LOCALE)) + { + return cal_rec->locale; + } + else if(0 == strcmp(field,CAL_TABLE_INT_COUNTRY)) + { + return cal_rec->country; + } + else if(0 == strcmp(field,CAL_TABLE_INT_TIME_ZONE)) + { + return cal_rec->time_zone; + } + else if(0 == strcmp(field,CAL_TABLE_INT_DISPLAY_ALL_TIMEZONES)) + { + return cal_rec->display_all_timezones; + } + else if(0 == strcmp(field,CAL_TABLE_INT_DATE_FIELD_ORDER)) + { + return cal_rec->date_field_order; + } + else if(0 == strcmp(field,CAL_TABLE_INT_FROMAT_24HOUR_TIME)) + { + return cal_rec->format_24hour_time; + } + else if(0 == strcmp(field,CAL_TABLE_INT_WEEK_START)) + { + return cal_rec->week_start; + } + else if(0 == strcmp(field,CAL_TABLE_INT_DEFAULT_CAL_MODE)) + { + return cal_rec->default_cal_mode; + } + else if(0 == strcmp(field,CAL_TABLE_INT_CUSTOM_CAL_MODE)) + { + return cal_rec->custom_cal_mode; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SHOW_DECLINED_EVENTS)) + { + return cal_rec->show_declined_events; + } + else if(0 == strcmp(field,CAL_TABLE_INT_HIDE_INVITATIONS)) + { + return cal_rec->hide_invitations; + } + else if(0 == strcmp(field,CAL_TABLE_INT_ALTERNATE_CALENDAR)) + { + return cal_rec->alternate_calendar; + } + else if(0 == strcmp(field,CAL_TABLE_INT_VISIBILITY)) + { + return cal_rec->visibility; + } + else if(0 == strcmp(field,CAL_TABLE_INT_PROJECTION)) + { + return cal_rec->projection; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SEQUENCE)) + { + return cal_rec->sequence; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SUPRESS_REPLY_NOTIFICATIONS)) + { + return cal_rec->suppress_reply_notifications; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SYNC_EVENT)) + { + return cal_rec->sync_event; + } + else if(0 == strcmp(field,CAL_TABLE_INT_TIMES_CLEANED)) + { + return cal_rec->times_cleaned; + } + else if(0 == strcmp(field,CAL_TABLE_INT_GUESTS_CAN_MODIFY)) + { + return cal_rec->guests_can_modify; + } + else if(0 == strcmp(field,CAL_TABLE_INT_GUESTS_CAN_INVITE_OTHERS)) + { + return cal_rec->guests_can_invite_others; + } + else if(0 == strcmp(field,CAL_TABLE_INT_GUESTS_CAN_SEE_GUESTS)) + { + return cal_rec->guests_can_see_guests; + } + else if(0 == strcmp(field,CAL_TABLE_INT_ACCESS_LEVEL)) + { + return cal_rec->access_level; + } + else if(0 == strcmp(field,CAL_VALUE_INT_SYNC_STATUS)) + { + return cal_rec->sync_status; + } + else if(0 == strcmp(field,CAL_TABLE_INT_ACCOUNT_ID)) + { + return cal_rec->account_id; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SENSITIVITY)) + { + return cal_rec->sensitivity; + } + else if(0 == strcmp(field,CAL_TABLE_INT_STORE_TYPE)) + { + return cal_rec->store_type; + } + else + { + ERR("Can not find the field(%s)",field); + } + break; + case CAL_STRUCT_TYPE_TIMEZONE: + tz_rec = event->user_data; + if(0 == strcmp(field,CAL_TZ_VALUE_INT_INDEX)) + { + return tz_rec->index; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_TZ_OFFSET)) + { + return tz_rec->tz_offset_from_gmt; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_START_MONTH)) + { + return tz_rec->std_start_month; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_START_POSITION_OF_WEEK)) + { + return tz_rec->std_start_position_of_week; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_START_DAY)) + { + return tz_rec->std_start_day; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_START_HOUR)) + { + return tz_rec->std_start_hour; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_BIAS)) + { + return tz_rec->standard_bias; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_START_MONTH)) + { + return tz_rec->day_light_start_month; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_START_POSITION_OF_WEEK)) + { + return tz_rec->day_light_start_position_of_week; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_START_DAY)) + { + return tz_rec->day_light_start_day; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_START_HOUR)) + { + return tz_rec->day_light_start_hour; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_BIAS)) + { + return tz_rec->day_light_bias; + } + + break; + default: + break; + + } + + return 0; +} + +API time_t calendar_svc_struct_get_time (cal_struct *event, const char *field, int timezone_flag) +{ + time_t ret_time = 0; + cal_sch_full_t * sch_rec = NULL; + + retv_if(NULL == event, CAL_ERR_ARG_NULL); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + retv_if(NULL == event->user_data, CAL_ERR_ARG_INVALID); + + switch(event->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + sch_rec = (cal_sch_full_t*)event->user_data; + if(sch_rec==NULL) + { + return CAL_ERR_ARG_NULL; + } + + if(0 == strcmp(field,CAL_VALUE_GMT_START_DATE_TIME)) + { + ret_time = cals_mktime(&(sch_rec->start_date_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_END_DATE_TIME)) + { + ret_time = cals_mktime(&(sch_rec->end_date_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_REPEAT_END_DATE)) + { + ret_time = cals_mktime(&(sch_rec->repeat_end_date)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_LAST_MODIFIED_TIME)) + { + ret_time = cals_mktime(&(sch_rec->last_modified_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_CREATED_DATE_TIME)) + { + ret_time = cals_mktime(&(sch_rec->created_date_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_COMPLETED_DATE_TIME)) + { + ret_time = cals_mktime(&(sch_rec->completed_date_time)); + } + else + { + } + break; + + case CAL_STRUCT_TYPE_CALENDAR: + return 0; + break; + + default: + return 0; + break; + } + + if(timezone_flag != CAL_TZ_FLAG_GMT && sch_rec->all_day_event==false) + { + time_t temp = 0; + calendar_svc_util_gmt_to_local(ret_time,&temp); + ret_time = temp; + } + + return ret_time; +} + +API struct tm* calendar_svc_struct_get_tm(cal_struct* record, const char *field, int timezone_flag) +{ + struct tm* ret_tm = 0; + cal_sch_full_t * sch_rec = NULL; + + retv_if(NULL == record, NULL); + retv_if(NULL == field, NULL); + retv_if(NULL == record->user_data, NULL); + + switch(record->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + sch_rec = (cal_sch_full_t*)record->user_data; + if(sch_rec==NULL) + { + return NULL; + } + + if(0 == strcmp(field,CAL_VALUE_GMT_START_DATE_TIME)) + { + ret_tm = &(sch_rec->start_date_time); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_END_DATE_TIME)) + { + ret_tm = &(sch_rec->end_date_time); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_REPEAT_END_DATE)) + { + ret_tm = &(sch_rec->repeat_end_date); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_LAST_MODIFIED_TIME)) + { + ret_tm = &(sch_rec->last_modified_time); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_CREATED_DATE_TIME)) + { + ret_tm = &(sch_rec->created_date_time); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_COMPLETED_DATE_TIME)) + { + ret_tm = &(sch_rec->completed_date_time); + } + else + { + } + break; + + case CAL_STRUCT_TYPE_CALENDAR: + return NULL; + break; + + default: + return NULL; + break; + } + + + if(timezone_flag != CAL_TZ_FLAG_GMT && NULL != ret_tm && sch_rec->all_day_event==false) + { + time_t temp = 0; + time_t input_tt = 0; + + input_tt = cals_mktime(ret_tm); + + calendar_svc_util_gmt_to_local(input_tt,&temp); + input_tt = temp; + return cals_tmtime(&input_tt); + } + + //TMDUMP(*ret_tm); + return ret_tm; +} + + +API int calendar_svc_struct_set_int (cal_struct *event, const char *field, int intval) +{ + cal_sch_full_t * sch_rec = NULL; + calendar_t * cal_rec = NULL; + cal_timezone_t *tz_rec = NULL; + + retv_if(NULL == event, CAL_ERR_ARG_NULL); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + + switch(event->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + sch_rec = event->user_data; + if(0 == strcmp(field,CAL_VALUE_INT_INDEX)) + { + sch_rec->index = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ACCOUNT_ID)) + { + sch_rec->account_id = intval; + } + else if(0 == strcmp(field, CAL_VALUE_INT_CATEGORY)) + { + sch_rec->sch_category = intval; + } + else if(0 == strcmp(field, CAL_VALUE_INT_ALL_DAY_EVENT)) + { + sch_rec->all_day_event = !!(intval); + } + else if(0 == strcmp(field,CAL_VALUE_INT_REPEAT_TERM)) + { + sch_rec->repeat_term = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_REPEAT_INTERVAL)) + { + sch_rec->repeat_interval = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_REPEAT_OCCURRENCES)) + { + sch_rec->repeat_occurrences = intval; + sch_rec->repeat_end_date.tm_year = BASE_TIME_YEAR; + } + else if(0 == strcmp(field,CAL_VALUE_INT_DAY_DATE)) + { + sch_rec->day_date = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_FILE_ID)) + { + sch_rec->file_id = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_CONTACT_ID)) + { + sch_rec->contact_id = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_BUSY_STATUS)) + { + sch_rec->busy_status = intval; + } + else if(0 == strcmp(field, CAL_VALUE_INT_SENSITIVITY)) + { + sch_rec->sensitivity = intval; + } + else if(0 == strcmp(field, CAL_VALUE_INT_CALENDAR_TYPE)) + { + sch_rec->calendar_type = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_MEETING_STATUS)) + { + sch_rec->meeting_status = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_LOCATION_TYPE)) + { + sch_rec->location_type = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_CALENDAR_ID)) + { + sch_rec->calendar_id = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_DST)) + { + sch_rec->dst = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_SUN_MOON)) + { + sch_rec->sun_moon = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_WEEK_START)) + { + sch_rec->week_start = intval; + } + else if(0 == strcmp(field, CAL_VALUE_INT_ORIGINAL_EVENT_ID)) + { + sch_rec->original_event_id = intval; + } + else if(0 == strcmp(field, CAL_VALUE_INT_PRIORITY)) + { + sch_rec->priority = intval; + } + else if(0 == strcmp(field, CAL_VALUE_INT_SYNC_STATUS)) + { + sch_rec->sync_status = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_TASK_STATUS)) + { + sch_rec->task_status= intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_TIMEZONE)) + { + sch_rec->timezone= intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_EMAIL_ID)) + { + sch_rec->email_id= intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_AVAILABILITY)) + { + sch_rec->availability= intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_PROGRESS)) + { + sch_rec->progress = intval; + } + else + { + ERR("Invalid field(%d, %s)", event->event_type, field); + return CAL_ERR_ARG_INVALID; + } + break; + + case CAL_STRUCT_TYPE_CALENDAR: + cal_rec = event->user_data; + if(0 == strcmp(field,CAL_TABLE_INT_UPDATED)) + { + cal_rec->updated = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_HIDDEN)) + { + cal_rec->hidden = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SELECTED)) + { + cal_rec->selected = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_LOCALE)) + { + cal_rec->locale = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_COUNTRY)) + { + cal_rec->country = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_TIME_ZONE)) + { + cal_rec->time_zone = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_DISPLAY_ALL_TIMEZONES)) + { + cal_rec->display_all_timezones = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_DATE_FIELD_ORDER)) + { + cal_rec->date_field_order = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_FROMAT_24HOUR_TIME)) + { + cal_rec->format_24hour_time = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_WEEK_START)) + { + cal_rec->week_start = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_DEFAULT_CAL_MODE)) + { + cal_rec->default_cal_mode = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_CUSTOM_CAL_MODE)) + { + cal_rec->custom_cal_mode = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SHOW_DECLINED_EVENTS)) + { + cal_rec->show_declined_events = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_HIDE_INVITATIONS)) + { + cal_rec->hide_invitations = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_ALTERNATE_CALENDAR)) + { + cal_rec->alternate_calendar = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_VISIBILITY)) + { + cal_rec->visibility = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_PROJECTION)) + { + cal_rec->projection = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SEQUENCE)) + { + cal_rec->sequence = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SUPRESS_REPLY_NOTIFICATIONS)) + { + cal_rec->suppress_reply_notifications = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SYNC_EVENT)) + { + cal_rec->sync_event = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_TIMES_CLEANED)) + { + cal_rec->times_cleaned = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_GUESTS_CAN_MODIFY)) + { + cal_rec->guests_can_modify = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_GUESTS_CAN_INVITE_OTHERS)) + { + cal_rec->guests_can_invite_others = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_GUESTS_CAN_SEE_GUESTS)) + { + cal_rec->guests_can_see_guests = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_ACCESS_LEVEL)) + { + cal_rec->access_level = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SYNC_STATUS)) + { + cal_rec->sync_status = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_ACCOUNT_ID)) + { + cal_rec->account_id = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_SENSITIVITY)) + { + cal_rec->sensitivity = intval; + } + else if(0 == strcmp(field,CAL_TABLE_INT_STORE_TYPE)) + { + cal_rec->store_type = intval; + } + else + { + ERR("Invalid field(%d, %s)", event->event_type, field); + return CAL_ERR_ARG_INVALID; + } + break; + case CAL_STRUCT_TYPE_TIMEZONE: + tz_rec = event->user_data; + if(0 == strcmp(field,CAL_TZ_VALUE_INT_INDEX)) + { + tz_rec->index = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_TZ_OFFSET)) + { + tz_rec->tz_offset_from_gmt = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_START_MONTH)) + { + tz_rec->std_start_month = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_START_POSITION_OF_WEEK)) + { + tz_rec->std_start_position_of_week = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_START_DAY)) + { + tz_rec->std_start_day = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_START_HOUR)) + { + tz_rec->std_start_hour = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_STD_BIAS)) + { + tz_rec->standard_bias = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_START_MONTH)) + { + tz_rec->day_light_start_month = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_START_POSITION_OF_WEEK)) + { + tz_rec->day_light_start_position_of_week = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_START_DAY)) + { + tz_rec->day_light_start_day = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_START_HOUR)) + { + tz_rec->day_light_start_hour = intval; + } + else if(0 == strcmp(field,CAL_TZ_VALUE_INT_DST_BIAS)) + { + tz_rec->day_light_bias = intval; + } + else { + ERR("Invalid field(%d, %s)", event->event_type, field); + return CAL_ERR_ARG_INVALID; + } + break; + default: + ERR("Invalid field(%d, %s)", event->event_type, field); + return CAL_ERR_ARG_INVALID; + } + + return CAL_SUCCESS; +} + +API int calendar_svc_struct_set_str (cal_struct *event, const char *field, const char *strval) +{ + retex_if(NULL == event || NULL == field || NULL == strval,,"[ERROR]calendar_svc_struct_set_str:Invalid parameters.\n"); + + cal_sch_full_t *sch_rec = NULL; + calendar_t *cal_rec = NULL; + cal_timezone_t *tz_rec = NULL; + int str_len = strlen(strval)+1; + + switch(event->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + sch_rec = (cal_sch_full_t*)event->user_data; + if(0 == strcmp(field,CAL_VALUE_TXT_SUMMARY)) + { + CAL_FREE(sch_rec->summary); + + sch_rec->summary = (char*)malloc(str_len); + retex_if(NULL == sch_rec->summary,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->summary,0x00,str_len); + + strcpy(sch_rec->summary,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_DESCRIPTION)) + { + CAL_FREE(sch_rec->description); + + sch_rec->description = (char*)malloc(str_len); + retex_if(NULL == sch_rec->description,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->description,0x00,str_len); + + strcpy(sch_rec->description,strval); + } + else if(0 == strcmp(field, CAL_VALUE_TXT_LOCATION)) + { + CAL_FREE(sch_rec->location); + + + sch_rec->location = (char*)malloc(str_len); + retex_if(NULL == sch_rec->location,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->location,0x00,str_len); + + strcpy(sch_rec->location,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_WEEK_FLAG)) + { + CAL_FREE(sch_rec->week_flag); + + sch_rec->week_flag = (char*)malloc(str_len); + retex_if(NULL == sch_rec->week_flag,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->week_flag,0x00,str_len); + + strcpy(sch_rec->week_flag,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_UID)) + { + CAL_FREE(sch_rec->uid); + + sch_rec->uid = (char*)malloc(str_len); + retex_if(NULL == sch_rec->uid,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->uid,0x00,str_len); + + strcpy(sch_rec->uid,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ORGANIZER_NAME)) + { + CAL_FREE(sch_rec->organizer_name); + + + sch_rec->organizer_name = (char*)malloc(str_len); + retex_if(NULL == sch_rec->organizer_name,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->organizer_name,0x00,str_len); + + strcpy(sch_rec->organizer_name,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ORGANIZER_EMAIL )) + { + CAL_FREE(sch_rec->organizer_email); + + sch_rec->organizer_email = (char*)malloc(str_len); + retex_if(NULL == sch_rec->organizer_email,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->organizer_email,0x00,str_len); + + strcpy(sch_rec->organizer_email,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_GCAL_ID )) + { + CAL_FREE(sch_rec->gcal_id); + + + sch_rec->gcal_id = (char*)malloc(str_len); + retex_if(NULL == sch_rec->gcal_id,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->gcal_id,0x00,str_len); + + strcpy(sch_rec->gcal_id,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_UPDATED)) + { + CAL_FREE(sch_rec->updated); + + + sch_rec->updated = (char*)malloc(str_len); + retex_if(NULL == sch_rec->updated,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->updated,0x00,str_len); + + strcpy(sch_rec->updated,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_LOCATION_SUMMARY)) + { + CAL_FREE(sch_rec->location_summary); + + + sch_rec->location_summary = (char*)malloc(str_len); + retex_if(NULL == sch_rec->location_summary,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->location_summary,0x00,str_len); + + strcpy(sch_rec->location_summary,strval); + } + else if(0 == strcmp(field, CAL_VALUE_TXT_ETAG)) + { + CAL_FREE(sch_rec->etag); + + sch_rec->etag = (char*)malloc(str_len); + retex_if(NULL == sch_rec->etag,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->etag,0x00,str_len); + + strcpy(sch_rec->etag,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_EDIT_URL)) + { + CAL_FREE(sch_rec->edit_uri); + + sch_rec->edit_uri = (char*)malloc(str_len); + retex_if(NULL == sch_rec->edit_uri,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->edit_uri,0x00,str_len); + + strcpy(sch_rec->edit_uri,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_GEDERID)) + { + CAL_FREE(sch_rec->gevent_id); + + sch_rec->gevent_id = (char*)malloc(str_len); + retex_if(NULL == sch_rec->gevent_id,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->gevent_id,0x00,str_len); + + strcpy(sch_rec->gevent_id,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_TZ_NAME)) + { + CAL_FREE(sch_rec->tz_name); + + + sch_rec->tz_name = (char*)malloc(str_len); + retex_if(NULL == sch_rec->tz_name,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->tz_name,0x00,str_len); + + strcpy(sch_rec->tz_name,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_TZ_CITY_NAME)) + { + CAL_FREE(sch_rec->tz_city_name); + + + sch_rec->tz_city_name = (char*)malloc(str_len); + retex_if(NULL == sch_rec->tz_city_name,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(sch_rec->tz_city_name,0x00,str_len); + + strcpy(sch_rec->tz_city_name,strval); + } + else + { + retex_if(true,,"Can not find the field(%s)", field); + } + break; + + case CAL_STRUCT_TYPE_CALENDAR: + cal_rec = (calendar_t*)event->user_data; + + if(0 == strcmp(field,CAL_TABLE_TXT_CALENDAR_ID)) + { + CAL_FREE(cal_rec->calendar_id); + + cal_rec->calendar_id = (char*)malloc(str_len); + retex_if(NULL == cal_rec->calendar_id,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->calendar_id,0x00,str_len); + + strcpy(cal_rec->calendar_id,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_UID)) + { + CAL_FREE(cal_rec->uid); + + + cal_rec->uid = (char*)malloc(str_len); + retex_if(NULL == cal_rec->uid,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->uid,0x00,str_len); + + strcpy(cal_rec->uid,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_LINK)) + { + CAL_FREE(cal_rec->link); + + + cal_rec->link = (char*)malloc(str_len); + retex_if(NULL == cal_rec->link,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->link,0x00,str_len); + + strcpy(cal_rec->link,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_NAME)) + { + CAL_FREE(cal_rec->name); + + + cal_rec->name = (char*)malloc(str_len); + retex_if(NULL == cal_rec->name,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->name,0x00,str_len); + + strcpy(cal_rec->name,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_DESCRIPTION)) + { + CAL_FREE(cal_rec->description); + + + cal_rec->description = (char*)malloc(str_len); + retex_if(NULL == cal_rec->description,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->description,0x00,str_len); + + strcpy(cal_rec->description,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_AUTHOR)) + { + CAL_FREE(cal_rec->author); + + cal_rec->author = (char*)malloc(str_len); + retex_if(NULL == cal_rec->author,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->author,0x00,str_len); + + strcpy(cal_rec->author,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_COLOR)) + { + CAL_FREE(cal_rec->color); + + + cal_rec->color = (char*)malloc(str_len); + retex_if(NULL == cal_rec->color,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->color,0x00,str_len); + + strcpy(cal_rec->color,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_LOCATION)) + { + CAL_FREE(cal_rec->location); + + cal_rec->location = (char*)malloc(str_len); + retex_if(NULL == cal_rec->location,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->location,0x00,str_len); + + strcpy(cal_rec->location,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_TIME_ZONE_LABEL)) + { + CAL_FREE(cal_rec->timezone_label); + + cal_rec->timezone_label = (char*)malloc(str_len); + retex_if(NULL == cal_rec->timezone_label,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->timezone_label,0x00,str_len); + + strcpy(cal_rec->timezone_label,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_USER_LOCATION)) + { + CAL_FREE(cal_rec->user_location); + + + cal_rec->user_location = (char*)malloc(str_len); + retex_if(NULL == cal_rec->user_location,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->user_location,0x00,str_len); + + strcpy(cal_rec->user_location,strval); + } + else if(0 == strcmp(field,CAL_TABLE_TXT_WEATHER)) + { + CAL_FREE(cal_rec->weather); + + + cal_rec->weather = (char*)malloc(str_len); + retex_if(NULL == cal_rec->weather,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(cal_rec->weather,0x00,str_len); + + strcpy(cal_rec->weather,strval); + } + else + { + retex_if(true,,"[ERROR]calendar_svc_struct_set_str:Can not find the field!\n"); + } + + break; + case CAL_STRUCT_TYPE_TIMEZONE: + tz_rec = (cal_timezone_t*)event->user_data; + if(0 == strcmp(field,CAL_TZ_VALUE_TXT_STD_NAME)) + { + CAL_FREE(tz_rec->standard_name); + + + tz_rec->standard_name = (char*)malloc(str_len); + retex_if(NULL == tz_rec->standard_name,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(tz_rec->standard_name,0x00,str_len); + + strcpy(tz_rec->standard_name,strval); + } + else if(0 == strcmp(field,CAL_TZ_VALUE_TXT_DST_NAME)) + { + CAL_FREE(tz_rec->day_light_name); + + tz_rec->day_light_name = (char*)malloc(str_len); + retex_if(NULL == tz_rec->day_light_name,,"[ERROR]calendar_svc_struct_set_str:Failed to malloc!\n"); + memset(tz_rec->day_light_name,0x00,str_len); + + strcpy(tz_rec->day_light_name,strval); + } + break; + + default: + ERR("Unknown event type(%d)", event->event_type); + return CAL_ERR_ARG_INVALID; + } + + return CAL_SUCCESS; + +CATCH: + + return CAL_ERR_FAIL; + +} + +API int calendar_svc_struct_set_time (cal_struct *event, const char *field,int timezone_flag, time_t time) +{ + cal_sch_full_t *sch_rec = NULL; + + retv_if(NULL == event, CAL_ERR_ARG_NULL); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + + if(timezone_flag != CAL_TZ_FLAG_GMT) + { + time_t temp = 0; + calendar_svc_util_local_to_gmt(time,&temp); + time = temp; + } + + switch(event->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + + sch_rec = (cal_sch_full_t*)event->user_data; + if(sch_rec==NULL) + { + return CAL_ERR_ARG_NULL; + } + if(0 == strcmp(field,CAL_VALUE_GMT_START_DATE_TIME)) + { + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&time),&(sch_rec->start_date_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_END_DATE_TIME)) + { + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&time),&(sch_rec->end_date_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_REPEAT_END_DATE)) + { + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&time),&(sch_rec->repeat_end_date)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_LAST_MODIFIED_TIME)) + { + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&time),&(sch_rec->last_modified_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_CREATED_DATE_TIME)) + { + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&time),&(sch_rec->created_date_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_COMPLETED_DATE_TIME)) + { + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&time),&(sch_rec->completed_date_time)); + } + else + { + } + + break; + + case CAL_STRUCT_TYPE_CALENDAR: + + break; + + default: + break; + } + + return CAL_SUCCESS; +} + + +API int calendar_svc_struct_set_tm(cal_struct* record, const char *field, int timezone_flag,struct tm* time) +{ + cal_sch_full_t * sch_rec = NULL; + struct tm input_tm ={0}; + + retv_if(NULL == record, CAL_ERR_ARG_NULL); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + + if(timezone_flag != CAL_TZ_FLAG_GMT) + { + time_t temp = 0; + time_t input_tt = 0; + + input_tt = cals_mktime(time); + calendar_svc_util_local_to_gmt(input_tt,&temp); + input_tt = temp; + cals_tmtime_r(&input_tt,&input_tm); + } + else + memcpy(&input_tm,time,sizeof(struct tm)); + + switch(record->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + + sch_rec = (cal_sch_full_t*)record->user_data; + if(sch_rec==NULL) + { + return CAL_ERR_ARG_NULL; + } + if(0 == strcmp(field,CAL_VALUE_GMT_START_DATE_TIME)) + { + cal_db_service_copy_struct_tm(&input_tm,&(sch_rec->start_date_time)); + TMDUMP(input_tm); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_END_DATE_TIME)) + { + cal_db_service_copy_struct_tm(&input_tm,&(sch_rec->end_date_time)); + TMDUMP(input_tm); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_REPEAT_END_DATE)) + { + cal_db_service_copy_struct_tm(&input_tm,&(sch_rec->repeat_end_date)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_LAST_MODIFIED_TIME)) + { + cal_db_service_copy_struct_tm(&input_tm,&(sch_rec->last_modified_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_CREATED_DATE_TIME)) + { + cal_db_service_copy_struct_tm(&input_tm,&(sch_rec->created_date_time)); + } + else if(0 == strcmp(field,CAL_VALUE_GMT_COMPLETED_DATE_TIME)) + { + cal_db_service_copy_struct_tm(&input_tm,&(sch_rec->completed_date_time)); + } + else + { + } + + break; + + case CAL_STRUCT_TYPE_CALENDAR: + + break; + + default: + break; + } + + return CAL_SUCCESS; +} + + +API double calendar_svc_struct_get_double(cal_struct* record, const char *field) +{ + double ret_val = 0.0; + cal_sch_full_t *sch_rec = NULL; + + retv_if(NULL == record, 0.0); + retv_if(NULL == field, 0.0); + retv_if(NULL == record->user_data, 0.0); + + switch(record->event_type) { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + sch_rec = record->user_data; + if(0 == strcmp(field,CAL_VALUE_DBL_LATITUDE)) + ret_val = sch_rec->latitude; + else if(0 == strcmp(field,CAL_VALUE_DBL_LONGITUDE)) + ret_val = sch_rec->longitude; + else + ERR("Unknown field(%s)", field); + break; + default: + ERR("Unknown event type(%d)", record->event_type); + break; + } + + return ret_val; +} + +API int calendar_svc_struct_set_double(cal_struct* record, const char *field,double value) +{ + cal_sch_full_t * sch_rec = NULL; + + retv_if(NULL == record, CAL_ERR_ARG_NULL); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + retv_if(NULL == record->user_data, CAL_ERR_ARG_INVALID); + + switch(record->event_type) + { + case CAL_STRUCT_TYPE_SCHEDULE: + case CAL_STRUCT_TYPE_TODO: + sch_rec = record->user_data; + if(0 == strcmp(field,CAL_VALUE_DBL_LATITUDE)) + sch_rec->latitude = value; + else if(0 == strcmp(field,CAL_VALUE_DBL_LONGITUDE)) + sch_rec->longitude = value; + else { + ERR("Unknown field(%s)", field); + return CAL_ERR_ARG_INVALID; + } + break; + default: + ERR("Unknown event type(%d)", record->event_type); + return CAL_ERR_ARG_INVALID; + } + + return CAL_SUCCESS; +} + + + +API int calendar_svc_struct_get_list (cal_struct *event, const char *field, GList **retlist) +{ + cal_sch_full_t * sch_rec = NULL; + + retv_if(NULL == event, CAL_ERR_ARG_NULL); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + retv_if(NULL == event->user_data, CAL_ERR_ARG_INVALID); + + switch(event->event_type) { + case CAL_STRUCT_TYPE_SCHEDULE: + sch_rec = (cal_sch_full_t*)event->user_data; + if(0 == strcmp(field, CAL_VALUE_LST_MEETING_CATEGORY)) + *retlist = sch_rec->meeting_category; + else if(0 == strcmp(field,CAL_VALUE_LST_ATTENDEE_LIST)) + *retlist = sch_rec->attendee_list; + else if(0 == strcmp(field, CAL_VALUE_LST_EXCEPTION_DATE)) + *retlist = sch_rec->exception_date_list; + else if(0 == strcmp(field, CAL_VALUE_LST_ALARM)) + *retlist = sch_rec->alarm_list; + else { + ERR("Unknown field(%s)", field); + return CAL_ERR_ARG_INVALID; + } + break; + case CAL_STRUCT_TYPE_TODO: + case CAL_STRUCT_TYPE_CALENDAR: + default: + ERR("Unknown event type(%d)", event->event_type); + return CAL_ERR_ARG_INVALID; + } + + return CAL_SUCCESS; +} + + + +static int _cals_struct_remove_list(const char *field, GList *list) +{ + GList *pList = list; + + while(pList) + { + calendar_svc_value_free((cal_value**)&pList->data); + + pList = pList->next; + } + g_list_free(list); + return 0; +} + + +API int calendar_svc_struct_store_list (cal_struct *event, const char *field, GList *list) +{ + cal_sch_full_t *sch_rec = NULL; + + retv_if(NULL == event, CAL_ERR_ARG_NULL); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + retv_if(NULL == event->user_data, CAL_ERR_ARG_INVALID); + + switch(event->event_type) { + case CAL_STRUCT_TYPE_SCHEDULE: + sch_rec = (cal_sch_full_t*)event->user_data; + if(0 == strcmp(field,CAL_VALUE_LST_MEETING_CATEGORY)) + { + if(list == NULL) + _cals_struct_remove_list(field,sch_rec->meeting_category); + + sch_rec->meeting_category = list; + } + else if(0 == strcmp(field,CAL_VALUE_LST_ATTENDEE_LIST)) + { + if(list == NULL) + _cals_struct_remove_list(field,sch_rec->attendee_list); + + sch_rec->attendee_list = list; + } + else if(0 == strcmp(field,CAL_VALUE_LST_EXCEPTION_DATE)) + { + if(list == NULL) + _cals_struct_remove_list(field,sch_rec->exception_date_list); + + sch_rec->exception_date_list = list; + } + else if(0 == strcmp(field,CAL_VALUE_LST_ALARM)) + { + if(list == NULL) + _cals_struct_remove_list(field,sch_rec->alarm_list); + + sch_rec->alarm_list = list; + } + break; + + case CAL_STRUCT_TYPE_CALENDAR: + case CAL_STRUCT_TYPE_TODO: + default: + break; + } + + return CAL_SUCCESS; +} + +API cal_value* calendar_svc_value_new (const char *filed) +{ + CALS_FN_CALL; + cal_value* value = NULL; + + retex_if(NULL == filed,,"[ERROR]calendar_svc_value_new:Invalid parameters.\n"); + + value = (cal_value*)malloc(sizeof(cal_value)); + retex_if(NULL == value,,"[ERROR]calendar_svc_value_new:Failed to malloc!\n"); + + memset(value,0x00,sizeof(cal_value)); + + if(0 == strcmp(CAL_VALUE_LST_MEETING_CATEGORY,filed)) + { + value->v_type = CAL_EVENT_CATEGORY; + value->user_data = (cal_category_info_t*)malloc(sizeof(cal_category_info_t)); + retex_if(NULL == value->user_data,,"[ERROR]calendar_svc_value_new:Fail to malloc!\n"); + + memset(value->user_data,0,sizeof(cal_category_info_t)); + } + else if(0 == strcmp(CAL_VALUE_LST_ATTENDEE_LIST,filed)) + { + value->v_type = CAL_EVENT_PATICIPANT; + value->user_data = (cal_participant_info_t*)malloc(sizeof(cal_participant_info_t)); + retex_if(NULL == value->user_data,,"[ERROR]calendar_svc_value_new:Fail to malloc!\n"); + + memset(value->user_data,0,sizeof(cal_participant_info_t)); + } + else if(0 == strcmp(CAL_VALUE_LST_EXCEPTION_DATE,filed)) + { + value->v_type = CAL_EVENT_RECURRENCY; + value->user_data = (cal_exception_info_t*)malloc(sizeof(cal_exception_info_t)); + retex_if(NULL == value->user_data,,"[ERROR]calendar_svc_value_new:Fail to malloc!\n"); + + memset(value->user_data,0,sizeof(cal_exception_info_t)); + } + else if(0 == strcmp(CAL_VALUE_LST_ALARM,filed)) + { + value->v_type = CAL_EVENT_ALARM; + value->user_data = (cal_alarm_info_t*)malloc(sizeof(cal_alarm_info_t)); + retex_if(NULL == value->user_data,,"[ERROR]calendar_svc_value_new:Fail to malloc!\n"); + + memset(value->user_data,0,sizeof(cal_alarm_info_t)); + } + else + { + CAL_FREE(value); + + retex_if(true,,"[ERROR]calendar_svc_value_new:Invalid parameter!\n"); + } + DBG("- calendar_svc_value_new\n"); + return value; + +CATCH: + + CAL_FREE(value); + + + return NULL; +} + +static int calendar_svc_free_participant(cal_participant_info_t* value) +{ + CALS_FN_CALL; + if(NULL == value) + { + return CAL_SUCCESS; + } + + CAL_FREE(value->attendee_name); + CAL_FREE(value->attendee_email); + CAL_FREE(value->attendee_number); + CAL_FREE(value); + + + return CAL_SUCCESS; +} + +static int calendar_svc_free_category(cal_category_info_t* value) +{ + CALS_FN_CALL; + if(NULL == value) + { + return CAL_SUCCESS; + } + + CAL_FREE(value->category_name); + CAL_FREE(value); + + + return CAL_SUCCESS; +} + +static int calendar_svc_free_exception_info(cal_exception_info_t* value) +{ + CALS_FN_CALL; + + int error_code = 0; + + if(NULL == value) + { + return CAL_SUCCESS; + } + + if(NULL != value->exception_record) + { + cal_db_service_free_full_record(value->exception_record,&error_code); + free(value->exception_record); + } + + CAL_FREE(value); + + + return CAL_SUCCESS; +} + + +static int calendar_svc_free_alarm_info(cal_alarm_info_t* value) +{ + CALS_FN_CALL; + + if(value) { + free(value->alarm_tone); + free(value->alarm_description); + free(value); + } + + return CAL_SUCCESS; +} + + + +API int calendar_svc_value_free (cal_value **value) +{ + CALS_FN_CALL; + retex_if(NULL == value,,"[ERROR]calendar_svc_value_free:Invalid parameter!\n"); + retex_if(NULL == *value,,"[ERROR]calendar_svc_value_free:Invalid parameter!\n"); + + switch((*value)->v_type) + { + case CAL_EVENT_CATEGORY: + calendar_svc_free_category((cal_category_info_t*)(*value)->user_data); + break; + + case CAL_EVENT_PATICIPANT: + calendar_svc_free_participant((cal_participant_info_t*)(*value)->user_data); + break; + + case CAL_EVENT_RECURRENCY: + calendar_svc_free_exception_info((cal_exception_info_t*)(*value)->user_data); + break; + case CAL_EVENT_ALARM: + calendar_svc_free_alarm_info((cal_alarm_info_t*)(*value)->user_data); + break; + default: + break; + } + + CAL_FREE((*value)); + + + return CAL_SUCCESS; + +CATCH: + + return CAL_ERR_FAIL; + +} + + +API int calendar_svc_value_set_int (cal_value *value, const char *field, int intval) +{ + //CALS_FN_CALL(); + retex_if(NULL == value || NULL == value->user_data || NULL == field,,"[ERROR]calendar_svc_value_free:Invalid parameter!\n"); + + cal_category_info_t *category = NULL; + cal_participant_info_t *participant = NULL; + cal_exception_info_t *exception = NULL; + cal_alarm_info_t *alarm_info = NULL; + + + switch(value->v_type) + { + case CAL_EVENT_CATEGORY: + + category = (cal_category_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_INT_MEETING_CATEGORY_DETAIL_ID)) + { + category->event_id = intval; + } + else + { + } + break; + + case CAL_EVENT_PATICIPANT: + + participant = (cal_participant_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_DETAIL_STATUS)) + { + participant->attendee_status = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_DETAIL_TYPE)) + { + participant->attendee_type = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_DETAIL_CT_INDEX)) + { + participant->attendee_ct_index = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_ROLE)) + { + participant->attendee_role = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_RSVP)) + { + participant->attendee_rsvp = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_DETAIL_DELETE)) + { + participant->is_deleted= intval; + } + else + { + } + break; + case CAL_EVENT_RECURRENCY: + exception = (cal_exception_info_t*)value->user_data; + if(0 == strcmp(field,CAL_VALUE_INT_EXCEPTION_DATE_ID)) + { + exception->event_id = intval; + } + break; + case CAL_EVENT_ALARM: + alarm_info = (cal_alarm_info_t*)value->user_data; + if(0 == strcmp(field,CAL_VALUE_INT_ALARMS_TICK)) + { + alarm_info->remind_tick = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ALARMS_TICK_UNIT)) + { + alarm_info->remind_tick_unit = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ALARMS_TYPE)) + { + alarm_info->alarm_type = intval; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ALARMS_ID)) + { + alarm_info->alarm_id = intval; + } + + default: + break; + } + + return CAL_SUCCESS; + +CATCH: + + return CAL_ERR_FAIL; + +} + +API int calendar_svc_value_set_str (cal_value *value, const char *field, const char *strval) +{ + //CALS_FN_CALL(); + retex_if(NULL == value || NULL == value->user_data || NULL == field || NULL == strval,,"[ERROR]calendar_svc_value_free:Invalid parameter!\n"); + + cal_category_info_t* category = NULL; + cal_participant_info_t* participant = NULL; + cal_alarm_info_t *alarm_info = NULL; + + int str_len = strlen(strval)+1; + + switch(value->v_type) + { + case CAL_EVENT_CATEGORY: + + category = (cal_category_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_TXT_MEETING_CATEGORY_DETAIL_NAME)) + { + CAL_FREE(category->category_name); + + category->category_name = (char*)malloc(str_len); + retex_if(NULL == category->category_name,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(category->category_name ,0x00,str_len); + + strcpy(category->category_name,strval); + } + else + { + } + break; + + case CAL_EVENT_PATICIPANT: + + participant = (cal_participant_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME)) + { + CAL_FREE(participant->attendee_name); + + + participant->attendee_name = (char*)malloc(str_len); + retex_if(NULL == participant->attendee_name,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(participant->attendee_name,0x00,str_len); + + strcpy(participant->attendee_name,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DETAIL_EMAIL)) + { + CAL_FREE(participant->attendee_email); + + + participant->attendee_email = (char*)malloc(str_len); + retex_if(NULL == participant->attendee_email,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(participant->attendee_email,0x00,str_len); + + strcpy(participant->attendee_email,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DETAIL_NUMBER)) + { + CAL_FREE(participant->attendee_number); + + + participant->attendee_number = (char*)malloc(str_len); + retex_if(NULL == participant->attendee_number,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(participant->attendee_number,0x00,str_len); + + strcpy(participant->attendee_number,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_GROUP)) + { + CAL_FREE(participant->attendee_group); + + + participant->attendee_group = (char*)malloc(str_len); + retex_if(NULL == participant->attendee_group,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(participant->attendee_group,0x00,str_len); + + strcpy(participant->attendee_group,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DELEGATOR_URI)) + { + CAL_FREE(participant->attendee_delegator_uri); + + + participant->attendee_delegator_uri = (char*)malloc(str_len); + retex_if(NULL == participant->attendee_delegator_uri,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(participant->attendee_delegator_uri,0x00,str_len); + + strcpy(participant->attendee_delegator_uri,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DELEGATE_URI)) + { + CAL_FREE(participant->attendee_delegate_uri); + + + participant->attendee_delegate_uri = (char*)malloc(str_len); + retex_if(NULL == participant->attendee_delegate_uri,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(participant->attendee_delegate_uri,0x00,str_len); + + strcpy(participant->attendee_delegate_uri,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_UID)) + { + CAL_FREE(participant->attendee_uid); + + + participant->attendee_uid = (char*)malloc(str_len); + retex_if(NULL == participant->attendee_uid,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(participant->attendee_uid,0x00,str_len); + + strcpy(participant->attendee_uid,strval); + } + + else + { + } + break; + case CAL_EVENT_ALARM: + + alarm_info = (cal_alarm_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_TXT_ALARMS_TONE)) + { + CAL_FREE(alarm_info->alarm_tone); + + + alarm_info->alarm_tone = (char*)malloc(str_len); + retex_if(NULL == alarm_info->alarm_tone,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(alarm_info->alarm_tone,0x00,str_len); + + strcpy(alarm_info->alarm_tone,strval); + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ALARMS_DESCRIPTION)) + { + CAL_FREE(alarm_info->alarm_description); + + alarm_info->alarm_description = (char *)malloc(str_len); + retex_if(NULL == alarm_info->alarm_description,,"[ERROR]calendar_svc_value_set_str:Failed to malloc!\n"); + + memset(alarm_info->alarm_description,0x00,str_len); + + strcpy(alarm_info->alarm_description,strval); + } + break; + default: + break; + } + + return CAL_SUCCESS; + +CATCH: + + return CAL_ERR_FAIL; + +} + +API int calendar_svc_value_get_int (cal_value *value, const char *field) +{ + CALS_FN_CALL; + retex_if(NULL == value || NULL == value->user_data || NULL == field,,"[ERROR]calendar_svc_value_free:Invalid parameter!\n"); + + cal_category_info_t* category = NULL; + cal_participant_info_t* participant = NULL; + cal_exception_info_t * exception = NULL; + cal_alarm_info_t* alarm_info = NULL; + switch(value->v_type) + { + case CAL_EVENT_CATEGORY: + + category = (cal_category_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_INT_MEETING_CATEGORY_DETAIL_ID)) + { + return(category->event_id); + } + else + { + } + break; + + case CAL_EVENT_PATICIPANT: + + participant = (cal_participant_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_DETAIL_STATUS)) + { + return (participant->attendee_status); + } + else if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_DETAIL_TYPE)) + { + return (participant->attendee_type); + } + else if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_DETAIL_CT_INDEX)) + { + return participant->attendee_ct_index; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_ROLE)) + { + return participant->attendee_role; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ATTENDEE_RSVP)) + { + return participant->attendee_rsvp; + } + else + { + } + break; + case CAL_EVENT_RECURRENCY: + exception = (cal_exception_info_t*)value->user_data; + if(0 == strcmp(field,CAL_VALUE_INT_EXCEPTION_DATE_ID)) + { + return exception->event_id; + } + break; + case CAL_EVENT_ALARM: + alarm_info = (cal_alarm_info_t*)value->user_data; + if(0 == strcmp(field,CAL_VALUE_INT_ALARMS_TICK)) + { + return alarm_info->remind_tick; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ALARMS_TICK_UNIT)) + { + return alarm_info->remind_tick_unit; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ALARMS_TYPE)) + { + return alarm_info->alarm_type; + } + else if(0 == strcmp(field,CAL_VALUE_INT_ALARMS_ID)) + { + return alarm_info->alarm_id; + } + break; + default: + break; + } + + return CAL_SUCCESS; + +CATCH: + + return CAL_ERR_FAIL; + +} + +API char * calendar_svc_value_get_str (cal_value *value, const char *field) +{ + CALS_FN_CALL; + cal_category_info_t* category = NULL; + cal_participant_info_t* participant = NULL; + cal_alarm_info_t * alarm_info = NULL; + + retex_if(NULL == value || NULL == value->user_data || NULL == field,,"[ERROR]calendar_svc_value_free:Invalid parameter!\n"); + + switch(value->v_type) + { + case CAL_EVENT_CATEGORY: + category = (cal_category_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_TXT_MEETING_CATEGORY_DETAIL_NAME)) + { + return category->category_name; + } + break; + + case CAL_EVENT_PATICIPANT: + + participant = (cal_participant_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME)) + { + return participant->attendee_name; + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DETAIL_EMAIL)) + { + return participant->attendee_email; + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DETAIL_NUMBER)) + { + return participant->attendee_number; + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_GROUP)) + { + return participant->attendee_group; + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DELEGATOR_URI)) + { + return participant->attendee_delegator_uri; + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_DELEGATE_URI)) + { + return participant->attendee_delegate_uri; + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ATTENDEE_UID)) + { + return participant->attendee_uid; + } + break; + case CAL_EVENT_ALARM: + + alarm_info = (cal_alarm_info_t*)value->user_data; + + if(0 == strcmp(field,CAL_VALUE_TXT_ALARMS_TONE)) + { + return alarm_info->alarm_tone; + } + else if(0 == strcmp(field,CAL_VALUE_TXT_ALARMS_DESCRIPTION)) + { + return alarm_info->alarm_description; + } + break; + default: + break; + } + +CATCH: + + return NULL; + +} + + +API time_t calendar_svc_value_get_time (cal_value *value, const char *field,int timezone_flag) +{ + CALS_FN_CALL; + time_t ret_time = 0; + + retv_if(NULL == value, CAL_ERR_ARG_NULL); + retv_if(NULL == value->user_data, CAL_ERR_ARG_INVALID); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + + switch(value->v_type) + { + case CAL_EVENT_RECURRENCY: + if(0 == strcmp(field,CAL_VALUE_GMT_EXCEPTION_DATE_TIME)) + { + cal_exception_info_t *exception_info = value->user_data; + ret_time = cals_mktime(&(exception_info->exception_start_time)); + } + else + { + } + break; + case CAL_EVENT_ALARM: + if(0 == strcmp(field,CAL_VALUE_GMT_ALARMS_TIME)) + { + cal_alarm_info_t *alarm_info = value->user_data; + ret_time = cals_mktime(&(alarm_info->alarm_time)); + } + else + { + } + + break; + + default: + break; + } + + if(timezone_flag != CAL_TZ_FLAG_GMT) + { + time_t temp = 0; + calendar_svc_util_gmt_to_local(ret_time,&temp); + ret_time = temp; + } + + return ret_time; +} + +API struct tm* calendar_svc_value_get_tm (cal_value *value, const char *field,int timezone_flag) +{ + CALS_FN_CALL; + struct tm* ret_tm = 0; + + retv_if(NULL == value, NULL); + retv_if(NULL == value->user_data, NULL); + retv_if(NULL == field, NULL); + + switch(value->v_type) + { + case CAL_EVENT_RECURRENCY: + if(0 == strcmp(field,CAL_VALUE_GMT_EXCEPTION_DATE_TIME)) + { + cal_exception_info_t *exception_info = value->user_data; + ret_tm = &(exception_info->exception_start_time); + } + else + { + } + break; + case CAL_EVENT_ALARM: + if(0 == strcmp(field,CAL_VALUE_GMT_ALARMS_TIME)) + { + cal_alarm_info_t *alarm_info = value->user_data; + ret_tm = &(alarm_info->alarm_time); + } + else + { + } + break; + + default: + break; + } + + if(timezone_flag != CAL_TZ_FLAG_GMT && NULL != ret_tm) + { + time_t temp = 0; + time_t input_tt = 0; + + input_tt = cals_mktime(ret_tm); + + calendar_svc_util_gmt_to_local(input_tt,&temp); + input_tt = temp; + return cals_tmtime(&input_tt); + } + + return ret_tm; +} + + + +API int calendar_svc_value_set_time (cal_value *value, const char *field,int timezone_flag, time_t time) +{ + CALS_FN_CALL; + + retv_if(NULL == value, CAL_ERR_ARG_NULL); + retv_if(NULL == value->user_data, CAL_ERR_ARG_INVALID); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + + if(timezone_flag != CAL_TZ_FLAG_GMT) + { + time_t temp = 0; + calendar_svc_util_local_to_gmt(time,&temp); + time = temp; + } + + switch(value->v_type) + { + case CAL_EVENT_RECURRENCY: + if(0 == strcmp(field,CAL_VALUE_GMT_EXCEPTION_DATE_TIME)) + { + cal_exception_info_t *exception_info = value->user_data; + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&time),&(exception_info->exception_start_time)); + + return CAL_SUCCESS; + } + else + { + + } + break; + case CAL_EVENT_ALARM: + if(0 == strcmp(field,CAL_VALUE_GMT_ALARMS_TIME)) + { + cal_alarm_info_t *alarm_info = value->user_data; + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&time),&(alarm_info->alarm_time)); + + return CAL_SUCCESS; + } + else + { + + } + break; + + default: + break; + } + + return CAL_SUCCESS; +} + + + +API int calendar_svc_value_set_tm (cal_value *value, const char *field,int timezone_flag, struct tm* time) +{ + CALS_FN_CALL; + struct tm input_tm ={0}; + + retv_if(NULL == value, CAL_ERR_ARG_NULL); + retv_if(NULL == value->user_data, CAL_ERR_ARG_INVALID); + retv_if(NULL == field, CAL_ERR_ARG_NULL); + + if(timezone_flag != CAL_TZ_FLAG_GMT) + { + time_t temp = 0; + time_t input_tt = 0; + + input_tt = cals_mktime(time); + calendar_svc_util_local_to_gmt(input_tt,&temp); + input_tt = temp; + cals_tmtime_r(&input_tt,&input_tm); + } + else + memcpy(&input_tm,time,sizeof(struct tm)); + + + switch(value->v_type) + { + case CAL_EVENT_RECURRENCY: + if(0 == strcmp(field,CAL_VALUE_GMT_EXCEPTION_DATE_TIME)) + { + cal_exception_info_t *exception_info = value->user_data; + //cal_db_service_copy_struct_tm((struct tm*)&input_tm,&(exception_info->exception_start_time)); + memcpy(&(exception_info->exception_start_time),&input_tm,sizeof(struct tm)); + DBG("%d-%d-%d",exception_info->exception_start_time.tm_year,exception_info->exception_start_time.tm_mon,exception_info->exception_start_time.tm_mday); + return CAL_SUCCESS; + } + else + { + + } + break; + case CAL_EVENT_ALARM: + if(0 == strcmp(field,CAL_VALUE_GMT_ALARMS_TIME)) + { + cal_alarm_info_t *alarm_info = value->user_data; + //cal_db_service_copy_struct_tm((struct tm*)&input_tm,&(exception_info->exception_start_time)); + memcpy(&(alarm_info->alarm_time),&input_tm,sizeof(struct tm)); + DBG("%d-%d-%d",alarm_info->alarm_time.tm_year,alarm_info->alarm_time.tm_mon,alarm_info->alarm_time.tm_mday); + return CAL_SUCCESS; + } + else + { + + } + break; + + default: + break; + } + + return CAL_SUCCESS; +} diff --git a/src/cals-struct.h b/src/cals-struct.h new file mode 100755 index 0000000..cfd187d --- /dev/null +++ b/src/cals-struct.h @@ -0,0 +1,24 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef _CALENDAR_SVC_STRUCT_INTERNAL_H_ +#define _CALENDAR_SVC_STRUCT_INTERNAL_H_ + +int cals_init_full_record(cal_sch_full_t *sch_full_record); + +#endif // _CALENDAR_SVC_STRUCT_INTERNAL_H_ diff --git a/src/cals-todo.c b/src/cals-todo.c new file mode 100755 index 0000000..8856835 --- /dev/null +++ b/src/cals-todo.c @@ -0,0 +1,137 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include "cals-internal.h" +#include "cals-typedef.h" +#include "cals-sqlite.h" +#include "cals-db-info.h" +#include "cals-db.h" +#include "cals-utils.h" + +static inline void cals_todo_make_condition(int calendar_id, + time_t start_time, time_t end_time, + int priority, cals_status_t status, char *dest, int dest_size) +{ + int ret; + + ret = snprintf(dest, dest_size, "type = %d", CAL_EVENT_TODO_TYPE); + + if (calendar_id) + ret += snprintf(dest+ret, dest_size-ret, "AND calendar_id = %d", calendar_id); + + if (0 < start_time) + ret += snprintf(dest+ret, dest_size-ret, "AND start_date_time >= %ld", start_time); + + if (0 < end_time) + ret += snprintf(dest+ret, dest_size-ret, "AND start_date_time <= %ld", end_time); + + if (0 < priority) + ret += snprintf(dest+ret, dest_size-ret, "AND priority = %d", priority); + + if (0 < status) + ret += snprintf(dest+ret, dest_size-ret, "AND task_status = %d", status); +} + +/** + * This function gets count related with todo. + * If parameter is invalid(0, negative, etc.), it will be ignored + * If all parameters are invalid, this function return all todo count. + * + * @param[in] calendar_id calendar_id + * @param[in] start_time start time + * @param[in] end_time end time + * @param[in] priority priority(0~9) + * @param[in] status #cals_status_t + * @return The count number on success, Negative value(#cal_error) on error + */ +API int calendar_svc_todo_get_count(int calendar_id, time_t start_time, + time_t end_time, int priority, cals_status_t status) +{ + char query[CALS_SQL_MIN_LEN]; + char cond[CALS_SQL_MIN_LEN]; + + cals_todo_make_condition(calendar_id, start_time, end_time, priority, status, cond, sizeof(cond)); + + snprintf(query, sizeof(query), "SELECT COUNT(*) FROM %s WHERE is_deleted = 0 AND %s", + CALS_TABLE_SCHEDULE, cond); + + return cals_query_get_first_int_result(query); +} + + +API cal_iter* calendar_svc_todo_get_list(int calendar_id, time_t start_time, + time_t end_time, int priority, cals_status_t status) +{ + cal_iter *iter; + sqlite3_stmt *stmt = NULL; + char query[CALS_SQL_MAX_LEN]; + char cond[CALS_SQL_MIN_LEN]; + + cals_todo_make_condition(calendar_id, start_time, end_time, priority, status, cond, sizeof(cond)); + + sprintf(query,"SELECT * FROM %s WHERE is_deleted = 0 AND %s ORDER BY start_date_time", + CALS_TABLE_SCHEDULE, cond); + + stmt = cals_query_prepare(query); + retvm_if(NULL == stmt, NULL,"cals_query_prepare() Failed"); + + iter = calloc(1, sizeof(cal_iter)); + if (NULL == iter) { + sqlite3_finalize(stmt); + ERR("calloc() Failed(%d)", errno); + return NULL; + } + iter->i_type = CAL_STRUCT_TYPE_TODO; + iter->stmt = stmt; + + return CAL_SUCCESS; +} + +API int calendar_svc_todo_delete_all(int calendar_id) +{ + int ret; + char query[CALS_SQL_MAX_LEN] = {0}; + + sprintf(query, "UPDATE %s SET is_deleted = 1, sync_status = %d, last_modified_time = %ld " + "WHERE type = %d AND calendar_id = %d", + CALS_TABLE_SCHEDULE, CAL_SYNC_STATUS_DELETED, time(NULL), + CAL_EVENT_TODO_TYPE, calendar_id); + + ret = cals_begin_trans(); + retvm_if(CAL_SUCCESS != ret, ret, "cals_begin_trans() Failed(%d)", ret); + + ret = cals_query_exec(query); + if (CAL_SUCCESS != ret) { + cals_end_trans(false); + ERR("cals_query_exec() Failed(%d)", ret); + return ret; + } + cals_end_trans(true); + + cals_notify(CALS_NOTI_TYPE_TODO); + + return CAL_SUCCESS; +} + +API cal_iter* calendar_svc_todo_get_updated_list(int calendar_id, time_t timestamp) +{ + return cals_get_updated_list(CAL_EVENT_TODO_TYPE, calendar_id, timestamp); +} + diff --git a/src/cals-typedef.h b/src/cals-typedef.h new file mode 100755 index 0000000..d4a73f1 --- /dev/null +++ b/src/cals-typedef.h @@ -0,0 +1,612 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef _CALENDAR_SVC_TYPEDEF_H_ +#define _CALENDAR_SVC_TYPEDEF_H_ + +#include +#include + +#include "calendar-svc-provider.h" + +/* Definition */ +#define CAL_INVALID_INDEX (-1) + +#define CAL_SCH_SUMMARY_LEN_MAX 1024//256 /**< Summary string length of Schedule */ +#define CAL_SCH_DESCRIPTION_LEN_MAX 4096 /**< Description string length of Schedule */ + +#define CAL_RECORD_CNT_MAX 2000 /**< max record count */ + +#define CAL_YEAR_MIN 1900 /**< Start value of year's range */ +#define CAL_YEAR_MAX 2037 /**< End value of year's range */ +#define CAL_MONTH_CNT_MAX 12 /**< max month count */ +#define CAL_MONTH_CNT_MIN 1 /**< min month count */ +#define CAL_DAY_CNT_MAX 31 /**< max day count */ +#define BENCHMARK_YEAR 1900L /**< tm_year's benchmark */ +#define ONE_DAY_SECONDS 86400L /**< seconds in a day */ +#define ONE_WEEK_SECONDS 604800L /**< seconds in a week */ +#define ONE_MONTH_SECONDS 2678400L /**< seconds in a month */ +#define ONE_YEAR_SECONDS 31536000L /**< seconds in a year */ +#define DAY_OF_A_WEEK 7 /**< days of a week */ +#define MAX_REPEAT_OF_A_WEEK 9 /**< max repeat event count in week */ + +#define MONTH_MAX 11 +#define MONTH_DAY_MIN 1 +#define MONTH_DAY_MAX 31 +#define MONTH_MIN 0 + +#define TM_YEAR_MIN 0 +#define TM_YEAR_MAX 138 + +#define BASE_TIME_YEAR 70 + +#define CAL_EVENT_UID_MAX_COUNT 256 /**< Max count of calendar UID*/ + +typedef enum +{ + CAL_STRUCT_TYPE_SCHEDULE=0, /**< schedule type */ + CAL_STRUCT_TYPE_CALENDAR, /**< calendar type */ + CAL_STRUCT_TYPE_TODO, /**< task type */ + CAL_STRUCT_TYPE_TIMEZONE, + CAL_STRUCT_TYPE_SCHEDULE_LIST, + CAL_STRUCT_TYPE_TODO_LIST, +}cal_struct_type; + +typedef enum +{ + CAL_EVENT_PATICIPANT = 0, /**< CAL_STRUCT_PARTICIPANT */ + CAL_EVENT_CATEGORY, /**< CAL_STRUCT_CATEFORY */ + CAL_EVENT_RECURRENCY, /**< CAL_STRUCT_RECURRENCY */ + CAL_EVENT_DELETE, /**< CAL_STRUCT_DELETE */ + CAL_EVENT_SYNC_STATUS, /**< CAL_STRUCT_SYNC_STATUS */ + CAL_EVENT_CALENDAR, /**< CAL_STRUCT_CALENDAR */ + CAL_EVENT_ALARM, + CAL_EVENT_MAX, + +} cal_data_type_t; + +struct _cal_struct{ + cal_struct_type event_type; + void* user_data; +}; + +struct _cal_value{ + cal_data_type_t v_type; + void* user_data; +}; + +struct _cal_iter{ + int i_type; + sqlite3_stmt *stmt; + int is_patched; +}; + +typedef struct +{ + int localtime_offset; + int local_dst_offset; + char local_tz_name[50]; + struct tm start_local_dst_date_time; + struct tm start_local_std_date_time; + + int temptime_offset; + int temp_dst_offset; + char temp_tz_name[50]; + struct tm start_temp_dst_date_time; + struct tm start_temp_std_date_time; + + int is_initialize; + int is_used_calendar_tz; +} cal_svc_tm_info_t; + +typedef enum +{ + CALS_NOTI_TYPE_EVENT, + CALS_NOTI_TYPE_TODO, + CALS_NOTI_TYPE_CALENDAR, +}cals_noti_type; + +/** + * @enum cal_record_sort_t + * This enumeration defines record sort type. + */ +typedef enum +{ + CAL_SORT_BY_ID = 0, /**< get reocrds sort by id */ + CAL_SORT_BY_START_DATE, /**< get reocrds sort by start time */ + CAL_SORT_BY_END_DATE, /**< get reocrds sort by end time */ + CAL_SORT_BY_MODIFIED_DATE, /**< get reocrds sort by modified time */ + CAL_SORT_BY_STATUS, /**< get reocrds sort by status */ + CAL_SORT_BY_PRIORITY_TIME_ALPHABET, /**< get reocrds sort by priority->time->alphabet */ + CAL_SORT_BY_PRIORITY, /**< get reocrds sort by priority */ + +} cal_record_sort_t; + +/** + * @enum cal_record_asc_desc_t + * This enumeration defines event sort type. + */ +typedef enum +{ + CAL_SORT_ASC =0, /**< asc sort type */ + CAL_SORT_DESC /**< desc sort type */ +}cal_record_asc_desc_t; + +/** + * @enum calendar_type_t + * This enumeration defines calendar type. + */ +typedef enum +{ + CAL_ALL_CALENDAR =0, /**< all calendar type */ + CAL_PHONE_CALENDAR, /**< phone calendar type */ + CAL_ACTIVESYNC_CALENDAR, /**< activesync calendar type*/ + CAL_GOOGLE_CALENDAR /**< google calendar type*/ +}calendar_type_t; + +/** + * @enum cal_type_t + * This enumeration defines calendar event type. + */ +typedef enum +{ + CAL_EVENT_NONE=0, /**< None type */ + CAL_EVENT_SCHEDULE_TYPE, /**< schedule event type */ + CAL_EVENT_TODO_TYPE, /**< task event type */ + CAL_EVENT_MEMO_TYPE, /**< memo event type */ + CAL_EVENT_MAX_TYPE, /**< max type */ +} cal_event_type_t; + + +/** + * @enum cal_vCal_ver_t + * This enumeration defines vCalendar version. + */ +typedef enum +{ + CAL_VCAL_VER_1_0 = 0, /**< vCalendar ver 1.0 */ + CAL_VCAL_VER_2_0, /**< vCalendar ver 2.0 */ + CAL_VCAL_VER_UNKNOWN /**< vCalendar ver unknown */ +} cal_vCal_ver_t; + +/** + * @enum cal_filter_t + * This enumeration defines filter type for todo data. + */ +typedef enum +{ + CAL_TODO_FILTER_UNDONE = 1, /**< todo condition is undone */ + CAL_TODO_FILTER_DONE = 2, /**< todo condition is done */ + CAL_TODO_FILTER_OVER_DUE = 4, /**< todo condition is duration */ + CAL_TODO_FILTER_UNDONE_AND_DONE =3, /**< todo condition is undone and done */ + CAL_TODO_FILTER_UNDONE_AND_OVER_DUE = 5, /**< todo condition is undone and overdue */ + CAL_TODO_FILTER_DONE_AND_OVER_DUE = 6, /**< todo condition is done and overdue */ + CAL_TODO_FILTER_ALL = 7, /**< todo condition is all */ + + CAL_TODO_FILTER_MAX = CAL_TODO_FILTER_ALL +}cal_filter_t; + +/** + * @enum cal_priority_t + * This enumeration defines priority for todo data. + */ +typedef enum +{ + CAL_PRIORITY_LOW, /**< priority low */ + CAL_PRIORITY_MID, /**< priority middle */ + CAL_PRIORITY_HIGH /**< priority high */ +}cal_priority_t; + + +/** + * @enum cal_starting_day_type_t + * This enumeration defines starting day. + */ +typedef enum +{ + CAL_STARTING_DAY_SUNDAY=0, /**< starting day is sunday */ + CAL_STARTING_DAY_MONDAY /**< starting day is monday */ +} cal_starting_day_type_t; + + +typedef enum +{ + CAL_TIME_ZONE_GMT_L11, + CAL_TIME_ZONE_GMT_L10, + CAL_TIME_ZONE_GMT_L9, + CAL_TIME_ZONE_GMT_L8, + CAL_TIME_ZONE_GMT_L7, + CAL_TIME_ZONE_GMT_L6, + CAL_TIME_ZONE_GMT_L5, + CAL_TIME_ZONE_GMT_L45, + CAL_TIME_ZONE_GMT_L4, + CAL_TIME_ZONE_GMT_L35, + CAL_TIME_ZONE_GMT_L3, + CAL_TIME_ZONE_GMT_L2, + CAL_TIME_ZONE_GMT_L1, + CAL_TIME_ZONE_GMT_0, + CAL_TIME_ZONE_GMT_1, + CAL_TIME_ZONE_GMT_2, + CAL_TIME_ZONE_GMT_3, + CAL_TIME_ZONE_GMT_35, + CAL_TIME_ZONE_GMT_4, + CAL_TIME_ZONE_GMT_45, + CAL_TIME_ZONE_GMT_5, + CAL_TIME_ZONE_GMT_55, + CAL_TIME_ZONE_GMT_575, + CAL_TIME_ZONE_GMT_6, + CAL_TIME_ZONE_GMT_65, + CAL_TIME_ZONE_GMT_7, + CAL_TIME_ZONE_GMT_8, + CAL_TIME_ZONE_GMT_9, + CAL_TIME_ZONE_GMT_95, + CAL_TIME_ZONE_GMT_10, + CAL_TIME_ZONE_GMT_11, + CAL_TIME_ZONE_GMT_12, + CAL_TIME_ZONE_GMT_13, + + CAL_TIME_ZONE_COUNT_MAX +}cal_time_zone_t; + +/** + * This structure stores the information whether there is an event on specific month + * event_info description. + * 0 : none. + * 1 : event start or one day's event. + * 2 : event not start and not end date , if 3 more days event than, 12223 + * 3 : event end + * 4 : repeated event's start & end date is duplicated. + */ +typedef struct +{ + int index; /**< index of event */ + cal_sch_category_t cal_type; /**< category type */ + int all_day_event; /***< this event is all day event or not */ + struct tm start_date_time[MAX_REPEAT_OF_A_WEEK]; + struct tm end_date_time[MAX_REPEAT_OF_A_WEEK]; + int repeat_event_count; + //int event_info[ DAY_OF_A_WEEK ]; /**< event info in a month 0-none */ +}cal_weekly_event_info_t; + +/** + * This structure stores the information whether there is an event on specific month. + */ +typedef struct +{ + int year; /**< Specifies a year */ + int month; /**< Specifies a month */ + bool exist[CAL_DAY_CNT_MAX]; /**< There can be an event or not on specific date */ +}cal_event_info_t; /* Event data info for calendar */ + +/** + * This structure stores the information whether there is an event on specific month. + */ +typedef struct +{ + int year; /**< Specifies a year */ + int month; /**< Specifies a month */ + int index; /**< index of event */ + int event_info[CAL_DAY_CNT_MAX]; /**< event info in a month 0-none, 1-has */ +}cal_monthly_event_info_t; + +/** + * This structure defines schedule information. + */ +typedef struct +{ + int index; /**< Record index */ + int account_id; /**< Account_id */ + cal_event_type_t cal_type; /**< Calendar event type */ + cal_sch_category_t sch_category; /**< Category of schedule */ + + char *summary; /**< Summary, appointment, task: subject, birthday:Name */ + char *description; /**< Description,appointment, task: description, anniversary,holiday:occasion*/ + char *location; /**< Location */ + GList *meeting_category; /**< collection of categories */ + bool all_day_event; /**< All day event flag */ + struct tm start_date_time; /**< schedule:start time, anniv,holiday,birthday,memo,todo: date */ + struct tm end_date_time; /**< end time */ + GList *alarm_list; + cal_repeat_term_t repeat_term; /**< Repeat term */ + int repeat_interval; /**< Interval of repeat term */ + int repeat_occurrences; /**< occurrences of repeat */ + struct tm repeat_end_date; /**< End date for repeat */ + cal_date_type_t sun_moon; /**< Using sun or lunar calendar */ + cal_starting_day_type_t week_start; /**< Start day of a week */ + char *week_flag;//[DAY_OF_A_WEEK + 1]; /**< Indicate which day is select in a week */ + int day_date; /**< 0- for weekday(sun,mon,etc.), 1- for specific day(1,2.. Etc) */ + struct tm last_modified_time; /**< for PC Sync */ + bool missed; /**< Miss alarm flag */ + cals_status_t task_status; /**< current task status */ + cal_priority_t priority; /**< Priority */ + int timezone; /**< timezone of task */ + int file_id; /**< file id for attach or alarm tone*/ + int contact_id; /**< contact id for birthday in contact list */ + GList *attendee_list; /**< collection of attendee */ + int busy_status; /**< ACS, G : Flag of busy or not */ + int sensitivity; /**< ACS, G : The sensitivity (public, private, confidential). #cal_visibility_type_t*/ + int meeting_status; /**< ACS, G : The status of the meeting. */ + char *uid; /**< ACS, G : Unique ID of the meeting item */ + char *organizer_name; /**< ACS, G : Name of organizer(author) */ + char *organizer_email; /**< ACS, G : Email of organizer */ + calendar_type_t calendar_type; /**< ACS, G : Type(all,phone,google) of calendar */ + char *gcal_id; /**< G : Server id of calendar */ + bool deleted; /**< G : Flag for deleted */ + char *updated; /**< G : Updated time stamp */ + int location_type; /**< G : Location type */ + char *location_summary; /**< G : A simple string value that can be used as a representation of this location */ + char *etag; /**< G : ETAG of this event */ + int calendar_id; /**< G : id to map from calendar table */ + cal_sync_status_t sync_status; /**< G : Indication for event entry whether added/ modified/ deleted */ + char *edit_uri; /**< G : EditUri for google calendar */ + char *gevent_id; /**< G : Server id of an event */ + int dst; /**< dst of event */ + GList *exception_date_list; /**< exception dates */ + int original_event_id; /**< original event id for recurrency exception */ + double latitude; + double longitude; + char *tz_name; + char *tz_city_name; + int is_deleted; + int email_id; + int availability; + struct tm created_date_time; /**< created time */ + struct tm completed_date_time; /**< completed time */ + int progress; +}cal_sch_full_t; + + +/** + * This structure defines schedule information. + */ +typedef struct +{ + int index; /**< Record index */ + cal_event_type_t cal_type; /**< Calendar event type */ + cal_sch_category_t sch_category; /**< Category of schedule */ + + char *summary; /**< Summary, appointment, task: subject, birthday:Name */ + char *description; /**< Description,appointment, task: description, anniversary,holiday:occasion*/ + char *location; /**< Location */ + + bool all_day_event; /**< All day event flag */ + struct tm start_date_time; /**< schedule:start time, anniv,holiday,birthday,memo,todo: date */ + struct tm end_date_time; /**< end time */ + struct tm alarm_time; /**< alarm time */ + int remind_tick; /**< Alarms before remindTick */ + cal_sch_remind_tick_unit_t remind_tick_unit; /**< Remind tick unit */ + int alarm_id; /**< Alarm id */ + + cal_repeat_term_t repeat_term; /**< Repeat term */ + int repeat_interval; /**< Interval of repeat term */ + struct tm repeat_end_date; /**< End date for repeat */ + cal_date_type_t sun_moon; /**< Using sun or lunar calendar */ + cal_starting_day_type_t week_start; /**< Start day of a week */ + char *week_flag; /**< Indicate which day is select in a week */ + int day_date; /**< 0- for weekday(sun,mon,etc.), 1- for specific day(1,2.. Etc) */ + bool missed; /**< Miss alarm flag */ + + int participant_id; /** +#include + +#include "cals-internal.h" +#include "cals-tz-utils.h" + +struct tm cal_tm_value = {0}; + +struct tm* cals_tmtime(time_t *sec) +{ + struct tm* temp = gmtime_r(sec,&cal_tm_value); + + if(temp) + return &cal_tm_value; + else + return NULL; +} + +time_t cals_mktime(struct tm *date_time) +{ + return timegm(date_time); +} + +struct tm* cals_tmtime_r(time_t *ttTime, struct tm *tmTime) +{ + struct tm* pTmTime = NULL; + retvm_if(NULL == ttTime, NULL,"ttTime is NULL"); + retvm_if(NULL == tmTime, NULL,"tmTime is NULL"); + + pTmTime = (struct tm*)cals_tmtime(ttTime); + memcpy(tmTime,pTmTime,sizeof(struct tm)); + return pTmTime; +} + + diff --git a/src/cals-tz-utils.h b/src/cals-tz-utils.h new file mode 100755 index 0000000..ee90672 --- /dev/null +++ b/src/cals-tz-utils.h @@ -0,0 +1,666 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_TZ_UTILS_H__ +#define __CALENDAR_SVC_TZ_UTILS_H__ + +typedef struct _Time_Zone Time_Zone; +struct _Time_Zone +{ + char *city; + char *country; + char *gmt; + char *tz_path; +}; + +static const Time_Zone time_zone_array[] = +{ +{"Abidjan", "Ivory Coast", "GMT+0", "Africa/Abidjan"}, +{"Abu Dhabi", "United Arab Emirates", "GMT+4", "Asia/Dubai"}, +{"Accra", "Ghana", "GMT-10", "Africa/Accra"}, +{"Addis Ababa", "Ethiopia", "GMT+3", "Africa/Addis_Ababa"}, +{"Adelaide", "Australia", "GMT+9:30", "Australia/Adelaide"}, +{"Alaska", "United States of America", "GMT-9", "America/Nome"}, +{"Algiers", "Algeria", "GMT+1", "Africa/Algiers"}, +{"Almaty", "Kazakhstan", "GMT+6", "Asia/Almaty"}, +{"Ambon", "Indonesia", "GMT+1", "Asia/Jayapura"}, +{"Amman", "Jordan", "GMT+2", "Asia/Amman"}, +{"Amsterdam", "Netherlands", "GMT+1", "Europe/Amsterdam"}, +{"Anadyr", "Russia ", "GMT+12", "Asia/Anadyr"}, +{"Anchorage", "United States of America", "GMT-9", "America/Anchorage"}, +{"Ankara", "Turkey", "GMT+2", "Asia/Istanbul"}, +{"Antananarivo", "Madagascar", "GMT+3", "Indian/Antananarivo"}, +{"Ashgabat", "Turkmenistan", "GMT+5", "Asia/Ashgabat"}, +{"Asmera", "Eritrea", "GMT+3", "Africa/Asmara" /* not in zone.tab */ }, +{"Astana", "Kazakhstan", "GMT+6", "Asia/Almaty" /* not in zone.tab */ }, +{"Asuncion", "Paraguay", "GMT-4", "America/Asuncion"}, +{"Athens", "Greece", "GMT+2", "Europe/Athens"}, +{"Auckland", "New Zealand", "GMT+12", "Pacific/Auckland"}, +{"Austin", "United States of America", "GMT-6", "CST6CDT"}, +{"Azores", "Portugal", "GMT-1", "Atlantic/Azores"}, +{"Baghdad", "Iraq", "GMT+3", "Asia/Baghdad"}, +{"Baku", "Azerbaijan", "GMT+4", "Asia/Baku"}, +{"Baltimore", "United States of America", "GMT-5", "EST5EDT"}, +{"Bamako", "Mali", "GMT+0", "Africa/Bamako"}, +{"Bangkok", "Thailand", "GMT+7", "Asia/Bangkok"}, +{"Bangui", "Central African Republic", "GMT+1", "Africa/Bangui"}, +{"Barcelona", "Spain", "GMT+2", "Europe/Madrid"}, +{"Bari", "Italy", "GMT+1", "Europe/Rome"}, +{"Basse-Terre", "Guadeloupe", "GMT-4", "America/Guadeloupe"}, +{"Beijing", "China", "GMT+8", "Asia/Shanghai"}, +{"Beirut", "Lebanon", "GMT+2", "Asia/Beirut"}, +{"Belgrade", "Serbia", "GMT+1", "Europe/Belgrade"}, +{"Belize City", "Belize", "GMT-6", "America/Belize"}, +{"Berlin", "Germany", "GMT+1", "Europe/Berlin"}, +{"Bern", "Switzerland", "GMT+1", "Europe/Zurich"}, +{"Bishkek", "Kyrgyzstan", "GMT+6", "Asia/Bishkek"}, +{"Bissau", "Guinea Bissau", "GMT+0", "Africa/Bissau"}, +{"Bogota", "Colombia", "GMT-5", "America/Bogota"}, +{"Bologna", "Italy", "GMT+1", "Europe/Rome"}, +{"Boston", "United States of America", "GMT-5", "EST5EDT"}, +{"Brasilia", "Brazil", "GMT-3", "America/Sao_Paulo"}, +{"Bratislava", "Slovakia", "GMT+2", "Europe/Bratislava"}, +{"Bridgetown", "Barbados", "GMT-4", "America/Barbados"}, +{"Brisbane", "Australia", "GMT+10", "Australia/Brisbane"}, +{"Brussels", "Belgium", "GMT+1", "Europe/Brussels"}, +{"Bucharest", "Romania", "GMT+3", "Europe/Bucharest"}, +{"Budapest", "Hungary", "GMT+1", "Europe/Budapest"}, +{"Buenos Aires", "Argentina", "GMT-3", "America/Argentina/Buenos_Aires"}, +{"Cairo", "Egypt", "GMT+2", "Africa/Cairo"}, +{"Calgary", "Canada", "GMT-7", "MST7MDT"}, +{"Canary Islands", "Spain", "GMT+0", "Atlantic/Canary"}, +{"Canberra", "Australia", "GMT+10", "Australia/Canberra"}, +{"Canton", "China", "GMT+8", "Asia/Shanghai"}, +{"Cape Town", "Republic of South Africa", "GMT+2", "Africa/Johannesburg"}, +{"Caracas", "Venezuela", "GMT-4:30", "America/Caracas"}, +{"Cardiff", "Wales", "GMT+0", "Europe/London"}, +{"Casablanca", "Morocco", "GMT+0", "Africa/Casablanca"}, +{"Catanzaro", "Italy", "GMT+1", "Europe/Rome"}, +{"Cayenne", "French Guiana", "GMT-3", "America/Cayenne"}, +{"Charlotte", "United States of America", "GMT-5", "EST5EDT"}, +{"Charlotte Amalie", "United States Virgin Islands ", "GMT-5:30", "America/St_Thomas"}, +{"Chelyabinsk", "Russia ", "GMT+5", "Asia/Yekaterinburg"}, +{"Chennai", "India", "GMT+5:30", "Asia/Kolkata"}, +{"Chicago", "United States of America", "GMT-6", "America/Chicago"}, +{"Chisinau", "Moldova", "GMT+2", "Europe/Chisinau"}, +{"Chita", "Russia", "GMT+9", "Asia/Yakutsk"}, +{"Cleveland", "United States of America", "GMT-5", "EST5EDT"}, +{"Colombo", "Sri Lanka", "GMT+5:30", "Asia/Colombo"}, +{"Columbus", "United States of America", "GMT-5", "EST5EDT"}, +{"Conakry", "Guinea", "GMT+1", "Africa/Conakry"}, +{"Copenhagen", "Denmark", "GMT+1", "Europe/Copenhagen"}, +{"Cork", "Ireland", "GMT+0", "Europe/Dublin"}, +{"Crotone", "Italy", "GMT+1", "Europe/Rome"}, +{"Dakar", "Senegal", "GMT+0", "Africa/Dakar"}, +{"Dallas", "United States of America", "GMT-6", "CST6CDT"}, +{"Damascus", "Syria", "GMT+2", "Asia/Damascus"}, +{"Dar es Salaam", "Tanzania", "GMT+3", "Africa/Dar_es_Salaam"}, +{"Darwin", "Australia", "GMT+9:30", "Australia/Darwin"}, +{"Delhi", "India", "GMT+5:30", "Asia/Kolkata"}, +{"Denpasar", "Indonesia", "GMT+8", "Asia/Makassar"}, +{"Denver", "United States of America", "GMT-7", "America/Denver"}, +{"Detroit", "United States of America", "GMT-5", "America/Detroit"}, +{"Dhaka", "Bangladesh", "GMT+6", "Asia/Dhaka"}, +{"Diego Garcia", "United Kingdom", "GMT+5", "Indian/Chagos" /* not in zone.tab */ }, +{"Djibouti", "Djibouti", "GMT+3", "Africa/Djibouti"}, +{"Doha", "Qatar", "GMT+3", "Asia/Qatar"}, +{"Douala", "Cameroon", "GMT+1", "Africa/Douala"}, +{"Dubai", "United Arab Emirates", "GMT+4", "Asia/Dubai"}, +{"Dublin", "Ireland", "GMT+0", "Europe/Dublin"}, +{"Dushanbe", "Tajikistan", "GMT+5", "Asia/Dushanbe"}, +{"Easter Island", "Chile", "GMT-6", "Pacific/Easter"}, +{"Edinburgh", "Scotland", "GMT+0", "Europe/London"}, +{"El Paso", "United States of America", "GMT-7", "MST7MDT"}, +{"Florence", "Italy", "GMT+1", "Europe/Rome"}, +{"Fort-de-France", "Martinique", "GMT-4", "America/Martinique"}, +{"Freetown", "Sierra Leone", "GMT+0", "Africa/Freetown"}, +{"Gaborone", "Botswana", "GMT+2", "Africa/Gaborone"}, +{"Galapagos Islands", "Ecuador", "GMT-7", "Pacific/Galapagos"}, +{"Geneva", "Switzerland", "GMT+1", "Europe/Paris"}, +{"Genoa", "Italy", "GMT+1", "Europe/Rome"}, +{"Georgetown", "Guyana", "GMT-4", "America/Guyana"}, +{"Grytviken", "South Georgia", "GMT-2", "Atlantic/South_Georgia"}, +{"Guam", "United States of America", "GMT+10", "Pacific/Guam"}, +{"Guatemala City", "Guatemala", "GMT-6", "America/Guatemala"}, +{"Gustavia", "Saint Barthelemy", "GMT-4", "America/Antigua"}, +{"Halifax", "Canada", "GMT-4", "America/Halifax"}, +{"Hamburg", "Germany", "GMT+1", "Europe/Berlin"}, +{"Hanoi", "Vietnam", "GMT+7", "Asia/Ho_Chi_Minh"}, +{"Harare", "Zimbabwe", "GMT+2", "Africa/Harare"}, +{"Havana", "Cuba", "GMT-5", "America/Havana"}, +{"Hawaii", "United States of America", "GMT-10", "Pacific/Honolulu"}, +{"Helsinki", "Finland", "GMT+2", "Europe/Helsinki"}, +{"Hobart", "Australia", "GMT+10", "Australia/Hobart"}, +{"Hong Kong", "China", "GMT+8", "Asia/Hong_Kong"}, +{"Honolulu", "United States of America", "GMT-10", "Pacific/Honolulu"}, +{"Houston", "United States of America", "GMT-6", "CST6CDT"}, +{"Hovd", "Mongolia", "GMT+8", "Asia/Hovd"}, +{"Indianapolis", "United States of America", "GMT-5", "America/Indiana/Indianapolis"}, +{"Irkutsk", "Russia ", "GMT+8", "Asia/Irkutsk"}, +{"Islamabad", "Pakistan", "GMT+5", "Asia/Karachi"}, +{"Istanbul", "Turkey", "GMT+2", "Europe/Istanbul"}, +{"Izhevsk", "Russia ", "GMT+4", "Europe/Moscow"}, +{"Jakarta", "Indonesia", "GMT+7", "Asia/Jakarta"}, +{"Jeddah", "Saudi Arabia", "GMT+3", "Asia/Riyadh"}, +{"Jerusalem", "Israel", "GMT+2", "Asia/Jerusalem"}, +{"Johannesburg", "South Africa", "GMT+2", "Africa/Johannesburg"}, +{"Kabul", "Afghanistan", "GMT+4:30", "Asia/Kabul"}, +{"Kaliningrad", "Russia", "GMT+2", "Europe/Kaliningrad"}, +{"Kamchatka", "Russia ", "GMT+12", "Asia/Kamchatka"}, +{"Kampala", "Uganda", "GMT+3", "Africa/Kampala"}, +{"Karachi", "Pakistan", "GMT+5", "Asia/Karachi"}, +{"Kathmandu", "Nepal", "GMT+5:45", "Asia/Kathmandu"}, +{"Khabarovsk", "Russia ", "GMT+10", "Asia/Vladivostok"}, +{"Kharkiv", "Ukraine", "GMT+2", "Europe/Kiev"}, +{"Khartoum", "Sudan", "GMT+3", "Africa/Khartoum"}, +{"Kiev", "Ukraine", "GMT+2", "Europe/Kiev"}, +{"Kingston", "Canada", "GMT-5", "America/Toronto"}, /* not in zone.tab */ +{"Kingston", "Jamaica", "GMT-5", "America/Jamaica"}, +{"Kinshasa", "Democratic Republic of the Congo", "GMT+1", "Africa/Kinshasa"}, +{"Kolkata", "India", "GMT+5:30", "Asia/Kolkata"}, +{"Krasnoyarsk", "Russia ", "GMT+7", "Asia/Krasnoyarsk"}, +{"Kuala Lumpur", "Malaysia", "GMT+8", "Asia/Kuala_Lumpur"}, +{"Kuwait", "Kuwait", "GMT+3", "Asia/Kuwait"}, +{"Kyiv", "Ukraine", "GMT+2", "Europe/Kiev" /* not in zone.tab */ }, +{"Los Angeles", "United States of America", "GMT-7", "America/Los_Angeles"}, +{"La Paz", "Bolivia", "GMT-4", "America/La_Paz"}, +{"Lagos", "Nigeria", "GMT+1", "Africa/Lagos"}, +{"Las Vegas", "United States of America", "GMT-8", "PST8PDT"}, +{"Lima", "Peru", "GMT-5", "America/Lima"}, +{"Lisbon", "Portugal", "GMT+0", "Europe/Lisbon"}, +{"Ljubljana", "Slovakia", "GMT+1", "Europe/Ljubljana"}, +{"London", "United Kingdom", "GMT+0", "Europe/London"}, +{"Longhua", "China", "GMT+8", "Asia/Shanghai"}, +{"Louisville", "United States of America", "GMT-5", "America/Kentucky/Louisville"}, +{"Luanda", "Angola", "GMT+1", "Africa/Luanda"}, +{"Lubumbashi", "Democratic Republic of the Congo", "GMT+2", "Africa/Lubumbashi"}, +{"Lusaka", "Zambia", "GMT+2", "Africa/Lusaka"}, +{"Luxembourg", "Luxembourg", "GMT+1", "Europe/Luxembourg"}, +{"Lviv", "Ukraine", "GMT+2", "Europe/Kiev"}, +{"Macau", "China", "GMT+8", "Asia/Macau"}, +{"Madrid", "Spain", "GMT+2", "Europe/Madrid"}, +{"Magadan", "Russia ", "GMT+11", "Asia/Magadan"}, +{"Malabo", "Equaorial Guinea", "GMT+1", "Africa/Malabo"}, +{"Male", "Maldives", "GMT+5", "Indian/Maldives"}, +{"Managua", "Nicaragua", "GMT-6", "America/Managua"}, +{"Manama", "Bahrain", "GMT+3", "Asia/Bahrain"}, +{"Manila", "Philippines", "GMT+8", "Asia/Manila"}, +{"Maputo", "Mozambique", "GMT+2", "Africa/Maputo"}, +{"Marigot", "Saint Martin", "GMT-4", "America/Marigot"}, +{"Mazatlan", "Mexico", "GMT-7", "America/Mazatlan"}, +{"Mecca", "Saudi Arabia", "GMT+3", "Asia/Riyadh"}, +{"Melbourne", "Australia", "GMT+10", "Australia/Melbourne"}, +{"Memphis", "United States of America", "GMT-6", "CST6CDT"}, +{"Messina", "Italy", "GMT+1", "Europe/Rome"}, +{"Mexico City", "Mexico", "GMT-6", "America/Mexico_City"}, +{"Miami", "United States of America", "GMT-5", "EST5EDT"}, +{"Mid-Atlantic", "United States of America", "GMT-2", "America/New_York" /* not in zone.tab */ }, +{"Midway Atoll", "United States of America", "GMT-11", "Pacific/Midway"}, +{"Milan", "Italy", "GMT+1", "Europe/Rome"}, +{"Milwaukee", "United States of America", "GMT-6", "CST6CDT"}, +{"Minsk", "Belarus", "GMT+2", "Europe/Minsk"}, +{"Mogadishu", "Somalia", "GMT+2", "Africa/Mogadishu"}, +{"Monrovia", "Liberia", "GMT+0", "Africa/Monrovia"}, +{"Montevideo", "Uruguay", "GMT-3", "America/Montevideo"}, +{"Montreal", "Canada", "GMT-5", "America/Montreal"}, +{"Moscow", "Russia ", "GMT+3", "Europe/Moscow"}, +{"Mumbai", "India", "GMT+5:30", "Asia/Kolkata"}, +{"Munich", "Germany", "GMT+1", "Europe/Berlin"}, +{"Muscat", "Oman", "GMT+4", "Asia/Muscat"}, +{"Nairobi", "Kenya", "GMT+3", "Africa/Nairobi"}, +{"Naples", "Italy", "GMT+1", "Europe/Rome"}, +{"Naters", "Switzerland", "GMT+1", "Europe/Zurich"}, +{"Ndjamena", "Chad", "GMT+1", "Africa/Ndjamena"}, +{"New Delhi", "India", "GMT+5:30", "Asia/Kolkata" /* not in zone.tab */ }, +{"New York", "United States of America", "GMT-4", "America/New_York"}, +{"Newfoundland", "Canada", "GMT-3:30", "America/St_Johns"}, +{"Niamey", "Niger", "GMT+1", "Africa/Niamey"}, +{"Nouakchott", "Mauritania", "GMT+1", "Africa/Nouakchott"}, +{"Noumea", "New Caledonia", "GMT+11", "Pacific/Noumea"}, +{"Novokuznetsk", "Russia", "GMT+7", "Asia/Novokuznetsk"}, +{"Novosibirsk", "Russia", "GMT+6", "Asia/Novosibirsk"}, +{"Nuku'alofa", "Tonga", "GMT+13", "Pacific/Tongatapu"}, +{"Nuuk", "Greenland", "GMT-3", "America/Godthab"}, +{"Omsk", "Russia", "GMT+6", "Asia/Omsk"}, +{"Osaka", "Japan", "GMT+9", "Asia/Tokyo"}, +{"Ottawa", "Canada", "GMT-5", "EST5EDT"}, +{"Ouagadougou", "Burkina Faso", "GMT+0", "Africa/Ouagadougou"}, +{"Pago Pago", "Independent State of Samoa", "GMT-11", "Pacific/Pago_Pago"}, +{"Palermo", "Italy", "GMT+1", "Europe/Rome"}, +{"Panama City", "Panama", "GMT-6", "America/Panama"}, +{"Paramaribo", "Surinam", "GMT-3", "America/Paramaribo"}, +{"Paris", "France", "GMT+1", "Europe/Paris"}, +{"Perm", "Russia", "GMT+5", "Asia/Yekaterinburg"}, +{"Perth", "Australia", "GMT+8", "Australia/Perth"}, +{"Petropavlovsk-Kamchatskiy", "Russia ", "GMT+12", "Asia/Kamchatka"}, +{"Philadelphia", "United States of America", "GMT-5", "EST5EDT"}, +{"Phnom Penh ", "Cambodia", "GMT-5", "Asia/Phnom_Penh"}, +{"Phoenix", "United States of America", "GMT-7", "America/Phoenix"}, +{"Podgorica", "Montenegro", "GMT+1", "Europe/Podgorica"}, +{"Ponta Delgada", "Portugal", "GMT-1", "Atlantic/Azores"}, +{"Port Louis", "Mauritius", "GMT+4", "Indian/Mauritius"}, +{"Port-au-Prince", "Haiti", "GMT-5", "America/Port-au-Prince"}, +{"Portland", "United States of America", "GMT-8", "PST8PDT"}, +{"Prague", "Czech Republic", "GMT+1", "Europe/Prague"}, +{"Pyongyang", "North Korea", "GMT+9", "Asia/Pyongyang"}, +{"Quito", "Ecuador", "GMT-5", "America/Guayaquil"}, +{"Rabat", "Morocco", "GMT+0", "Africa/Casablanca"}, +{"Rangoon", "Burma", "GMT+6:30", "Asia/Rangoon"}, +{"Recife", "Brazil", "GMT-3", "America/Recife"}, +{"Regina", "Canada", "GMT-6", "America/Regina"}, +{"Reykjavik", "Iceland", "GMT+0", "Atlantic/Reykjavik"}, +{"Riga", "Latvia", "GMT+2", "Europe/Riga"}, +{"Rio de Janeiro", "Brazil", "GMT-2", "America/Sao_Paulo"}, +{"Riyadh", "Saudi Arabia", "GMT+3", "Asia/Riyadh"}, +{"Rome", "Italy", "GMT+1", "Europe/Rome"}, +{"Saint-Denis", "Reunion Island", "GMT+4", "Indian/Reunion"}, +{"Samara", "Russia ", "GMT+4", "Europe/Samara"}, +{"San Antonio", "United States of America", "GMT-6", "CST6CDT"}, +{"San Diego", "United States of America", "GMT-8", "PST8PDT"}, +{"San Francisco", "United States of America", "GMT-8", "America/Los_Angeles"}, +{"San Jose", "United States of America", "GMT-8", "PST8PDT"}, +{"San Jose", "Costa Rica", "GMT-6", "America/Costa_Rica"}, +{"San Juan", "Puerto Rico", "GMT-4", "America/Puerto_Rico"}, +{"San Marino", "Italy", "GMT+1", "Europe/San_Marino"}, +{"San Salvador", "El Salvador", "GMT-6", "America/El_Salvador"}, +{"Sanaa", "Yemen", "GMT+3", "Asia/Aden" /* not in zone.tab */ }, +{"Santiago", "Chile", "GMT-4", "America/Santiago"}, +{"Santo Domingo", "Dominican Republic", "GMT-4", "America/Santo_Domingo"}, +{"Sao Paulo", "Brazil", "GMT-2", "America/Sao_Paulo"}, +{"Seattle", "United States of America", "GMT-8", "PST8PDT"}, +{"Seoul", "Republic of Korea", "GMT+9", "Asia/Seoul"}, +{"Shanghai", "China", "GMT+8", "Asia/Shanghai"}, +{"Shenzhen", "China", "GMT+8", "Asia/Shanghai"}, +{"Singapore", "Republic of Singapore", "GMT+8", "Asia/Singapore"}, +{"Skopje", "Macedonia", "GMT+1", "Europe/Skopje"}, +{"Sofia ", "Bulgaria", "GMT+3", "Europe/Sofia"}, +{"St. John's", "Antigua and Barbuda", "GMT-4", "America/Antigua"}, +{"St. John's", "Canada", "GMT-3:30", "America/St_Johns"}, +{"St. Petersburg", "Russia", "GMT+3", "Europe/Moscow"}, +{"Stockholm", "Sweden", "GMT+2", "Europe/Stockholm"}, +{"Suva", "Fiji", "GMT+12", "Pacific/Fiji"}, +{"Sydney", "Australia", "GMT+11", "Australia/Sydney"}, +{"Tahiti", "French Polynesia", "GMT-10", "Pacific/Tahiti"}, +{"Taipei", "Taiwan", "GMT+8", "Asia/Taipei"}, +{"Tallinn", "Estonia", "GMT+2", "Europe/Tallinn"}, +{"Tarawa", "Kiribati", "GMT+12", "Pacific/Tarawa"}, +{"Tashkent", "Uzbekistan", "GMT+5", "Asia/Tashkent"}, +{"Tbilisi", "Georgia", "GMT+4", "Asia/Tbilisi"}, +{"Tegucigalpa", "Honduras", "GMT-6", "America/Tegucigalpa"}, +{"Tehran", "Iran", "GMT+3:30", "Asia/Tehran"}, +{"Thanh Pho Ho Chi Minh", "Vietnam", "GMT+7", "Asia/Ho_Chi_Minh"}, +{"The Settlement", "British Virgin Islands ", "GMT-4", "America/Tortola"}, +{"Tientsin", "China", "GMT+8", "Asia/Shanghai" /* not in zone.tab */ }, +{"Tijuana", "Mexico", "GMT-5", "America/Tijuana"}, +{"Tokyo", "Japan", "GMT+9", "Asia/Tokyo"}, +{"Toronto", "Canada", "GMT-4", "America/Toronto"}, +{"Trehet", "France", "GMT+1", "Europe/Paris" /* not in zone.tab */ }, +{"Tripoli", "Libya", "GMT+2", "Africa/Tripoli"}, +{"Tunis", "Tunisia", "GMT+2", "Africa/Tunis"}, +{"Turin", "Italy", "GMT+1", "Europe/Rome"}, +{"Ufa", "Bashkiriya", "GMT+5", "Asia/Yekaterinburg"}, +{"Ulan Bator", "Mongolia", "GMT+8", "Asia/Ulan_Bator"}, +{"Vaduz", "Liechtenstein", "GMT+1", "Europe/Vaduz"}, +{"Valletta", "Malta", "GMT+1", "Europe/Malta"}, +{"Vancouver", "Canada", "GMT-8", "America/Vancouver"}, +{"Verona", "Italy", "GMT+1", "Europe/Rome"}, +{"Victoria", "Seychelles", "GMT+4", "Australia/Melbourne"}, +{"Vienna", "Austria", "GMT+1", "Europe/Vienna"}, +{"Vilnius", "Lithuania", "GMT+3", "Europe/Vilnius"}, +{"Vladivostok", "Russia ", "GMT+10", "Asia/Vladivostok"}, +{"Volgograd", "Russia ", "GMT+4", "Europe/Volgograd"}, +{"Warsaw", "Poland", "GMT+2", "Europe/Warsaw"}, +{"Washington, D.C.", "United States of America", "GMT-5", "EST5EDT"}, +{"Wellington", "New Zealand", "GMT+12", "Pacific/Auckland"}, +{"Winnipeg", "Canada", "GMT-5", "America/Winnipeg"}, +{"Yakutsk", "Russia ", "GMT+9", "Asia/Yakutsk"}, +{"Yamoussoukro", "Ivory Coast", "GMT+0", "Africa/Abidjan"}, +{"Yaounde", "Cameroon", "GMT+1", "Africa/Douala" /* not in zone.tab */ }, +{"Yekaterinburg", "Russia ", "GMT+5", "Asia/Yekaterinburg"}, +{"Yerevan", "Armenia", "GMT+5", "Asia/Yerevan"}, +{"Yuzhno-Sakhalinsk", "Russia ", "GMT+11", "Asia/Sakhalin"}, +{"Zagreb", "Croatia", "GMT+1", "Europe/Zagreb"}, +{"Zurich", "Switzerland", "GMT+1", "Europe/Zurich"}, +{NULL, NULL, NULL, NULL} +}; + +static const Time_Zone tz_path_array[] = +{ +{"Abidjan","Ivory Coast","GMT+0","Africa/Abidjan"}, +{"Yamoussoukro","Ivory Coast","GMT+0","Africa/Abidjan"}, +{"Accra","Ghana","GMT-10","Africa/Accra"}, +{"Addis Ababa","Ethiopia","GMT+3","Africa/Addis_Ababa"}, +{"Algiers","Algeria","GMT+1","Africa/Algiers"}, +{"Asmera","Eritrea","GMT+3","Africa/Asmara "}, +{"Bamako","Mali","GMT+0","Africa/Bamako"}, +{"Bangui","Central African Republic","GMT+1","Africa/Bangui"}, +{"Bissau","Guinea Bissau","GMT+0","Africa/Bissau"}, +{"Cairo","Egypt","GMT+2","Africa/Cairo"}, +{"Casablanca","Morocco","GMT+0","Africa/Casablanca"}, +{"Rabat","Morocco","GMT+0","Africa/Casablanca"}, +{"Conakry","Guinea","GMT+1","Africa/Conakry"}, +{"Dakar","Senegal","GMT+0","Africa/Dakar"}, +{"Dar es Salaam","Tanzania","GMT+3","Africa/Dar_es_Salaam"}, +{"Djibouti","Djibouti","GMT+3","Africa/Djibouti"}, +{"Douala","Cameroon","GMT+1","Africa/Douala"}, +{"Yaounde","Cameroon","GMT+1","Africa/Douala "}, +{"Freetown","Sierra Leone","GMT+0","Africa/Freetown"}, +{"Gaborone","Botswana","GMT+2","Africa/Gaborone"}, +{"Harare","Zimbabwe","GMT+2","Africa/Harare"}, +{"Cape Town","Republic of South Africa","GMT+2","Africa/Johannesburg"}, +{"Johannesburg","South Africa","GMT+2","Africa/Johannesburg"}, +{"Kampala","Uganda","GMT+3","Africa/Kampala"}, +{"Khartoum","Sudan","GMT+3","Africa/Khartoum"}, +{"Kinshasa","Democratic Republic of the Congo","GMT+1","Africa/Kinshasa"}, +{"Lagos","Nigeria","GMT+1","Africa/Lagos"}, +{"Luanda","Angola","GMT+1","Africa/Luanda"}, +{"Lubumbashi","Democratic Republic of the Congo","GMT+2","Africa/Lubumbashi"}, +{"Lusaka","Zambia","GMT+2","Africa/Lusaka"}, +{"Malabo","Equaorial Guinea","GMT+1","Africa/Malabo"}, +{"Maputo","Mozambique","GMT+2","Africa/Maputo"}, +{"Mogadishu","Somalia","GMT+2","Africa/Mogadishu"}, +{"Monrovia","Liberia","GMT+0","Africa/Monrovia"}, +{"Nairobi","Kenya","GMT+3","Africa/Nairobi"}, +{"Ndjamena","Chad","GMT+1","Africa/Ndjamena"}, +{"Niamey","Niger","GMT+1","Africa/Niamey"}, +{"Nouakchott","Mauritania","GMT+1","Africa/Nouakchott"}, +{"Ouagadougou","Burkina Faso","GMT+0","Africa/Ouagadougou"}, +{"Tripoli","Libya","GMT+2","Africa/Tripoli"}, +{"Tunis","Tunisia","GMT+2","Africa/Tunis"}, +{"Anchorage","United States of America","GMT-9","America/Anchorage"}, +{"Gustavia","Saint Barthelemy","GMT-4","America/Antigua"}, +{"St. John's","Antigua and Barbuda","GMT-4","America/Antigua"}, +{"Buenos Aires","Argentina","GMT-3","America/Argentina/Buenos_Aires"}, +{"Asuncion","Paraguay","GMT-4","America/Asuncion"}, +{"Bridgetown","Barbados","GMT-4","America/Barbados"}, +{"Belize City","Belize","GMT-6","America/Belize"}, +{"Bogota","Colombia","GMT-5","America/Bogota"}, +{"Caracas","Venezuela","GMT-4:30","America/Caracas"}, +{"Cayenne","French Guiana","GMT-3","America/Cayenne"}, +{"Chicago","United States of America","GMT-6","America/Chicago"}, +{"San Jose","Costa Rica","GMT-6","America/Costa_Rica"}, +{"Denver","United States of America","GMT-7","America/Denver"}, +{"Detroit","United States of America","GMT-5","America/Detroit"}, +{"San Salvador","El Salvador","GMT-6","America/El_Salvador"}, +{"Nuuk","Greenland","GMT-3","America/Godthab"}, +{"Basse-Terre","Guadeloupe","GMT-4","America/Guadeloupe"}, +{"Guatemala City","Guatemala","GMT-6","America/Guatemala"}, +{"Quito","Ecuador","GMT-5","America/Guayaquil"}, +{"Georgetown","Guyana","GMT-4","America/Guyana"}, +{"Halifax","Canada","GMT-4","America/Halifax"}, +{"Havana","Cuba","GMT-5","America/Havana"}, +{"Indianapolis","United States of America","GMT-5","America/Indiana/Indianapolis"}, +{"Kingston","Jamaica","GMT-5","America/Jamaica"}, +{"Louisville","United States of America","GMT-5","America/Kentucky/Louisville"}, +{"La Paz","Bolivia","GMT-4","America/La_Paz"}, +{"Lima","Peru","GMT-5","America/Lima"}, +{"Los Angeles","United States of America","GMT-7","America/Los_Angeles"}, +{"San Francisco","United States of America","GMT-8","America/Los_Angeles"}, +{"Managua","Nicaragua","GMT-6","America/Managua"}, +{"Marigot","Saint Martin","GMT-4","America/Marigot"}, +{"Fort-de-France","Martinique","GMT-4","America/Martinique"}, +{"Mazatlan","Mexico","GMT-7","America/Mazatlan"}, +{"Mexico City","Mexico","GMT-6","America/Mexico_City"}, +{"Montevideo","Uruguay","GMT-3","America/Montevideo"}, +{"Montreal","Canada","GMT-5","America/Montreal"}, +{"New York","United States of America","GMT-4","America/New_York"}, +{"Mid-Atlantic","United States of America","GMT-2","America/New_York "}, +{"Alaska","United States of America","GMT-9","America/Nome"}, +{"Panama City","Panama","GMT-6","America/Panama"}, +{"Paramaribo","Surinam","GMT-3","America/Paramaribo"}, +{"Phoenix","United States of America","GMT-7","America/Phoenix"}, +{"Port-au-Prince","Haiti","GMT-5","America/Port-au-Prince"}, +{"San Juan","Puerto Rico","GMT-4","America/Puerto_Rico"}, +{"Recife","Brazil","GMT-3","America/Recife"}, +{"Regina","Canada","GMT-6","America/Regina"}, +{"Santiago","Chile","GMT-4","America/Santiago"}, +{"Santo Domingo","Dominican Republic","GMT-4","America/Santo_Domingo"}, +{"Brasilia","Brazil","GMT-3","America/Sao_Paulo"}, +{"Rio de Janeiro","Brazil","GMT-2","America/Sao_Paulo"}, +{"Sao Paulo","Brazil","GMT-2","America/Sao_Paulo"}, +{"Newfoundland","Canada","GMT-3:30","America/St_Johns"}, +{"St. John's","Canada","GMT-3:30","America/St_Johns"}, +{"Charlotte Amalie","United States Virgin Islands ","GMT-5:30","America/St_Thomas"}, +{"Tegucigalpa","Honduras","GMT-6","America/Tegucigalpa"}, +{"Tijuana","Mexico","GMT-5","America/Tijuana"}, +{"Toronto","Canada","GMT-4","America/Toronto"}, +{"Kingston","Canada","GMT-5","America/Toronto "}, +{"The Settlement","British Virgin Islands ","GMT-4","America/Tortola"}, +{"Vancouver","Canada","GMT-8","America/Vancouver"}, +{"Winnipeg","Canada","GMT-5","America/Winnipeg"}, +{"Sanaa","Yemen","GMT+3","Asia/Aden "}, +{"Almaty","Kazakhstan","GMT+6","Asia/Almaty"}, +{"Astana","Kazakhstan","GMT+6","Asia/Almaty "}, +{"Amman","Jordan","GMT+2","Asia/Amman"}, +{"Anadyr","Russia","GMT+12","Asia/Anadyr"}, +{"Ashgabat","Turkmenistan","GMT+5","Asia/Ashgabat"}, +{"Baghdad","Iraq","GMT+3","Asia/Baghdad"}, +{"Manama","Bahrain","GMT+3","Asia/Bahrain"}, +{"Baku","Azerbaijan","GMT+4","Asia/Baku"}, +{"Bangkok","Thailand","GMT+7","Asia/Bangkok"}, +{"Beirut","Lebanon","GMT+2","Asia/Beirut"}, +{"Bishkek","Kyrgyzstan","GMT+6","Asia/Bishkek"}, +{"Colombo","Sri Lanka","GMT+5:30","Asia/Colombo"}, +{"Damascus","Syria","GMT+2","Asia/Damascus"}, +{"Dhaka","Bangladesh","GMT+6","Asia/Dhaka"}, +{"Abu Dhabi","United Arab Emirates","GMT+4","Asia/Dubai"}, +{"Dubai","United Arab Emirates","GMT+4","Asia/Dubai"}, +{"Dushanbe","Tajikistan","GMT+5","Asia/Dushanbe"}, +{"Hanoi","Vietnam","GMT+7","Asia/Ho_Chi_Minh"}, +{"Thanh Pho Ho Chi Minh","Vietnam","GMT+7","Asia/Ho_Chi_Minh"}, +{"Hong Kong","China","GMT+8","Asia/Hong_Kong"}, +{"Hovd","Mongolia","GMT+8","Asia/Hovd"}, +{"Irkutsk","Russia","GMT+8","Asia/Irkutsk"}, +{"Ankara","Turkey","GMT+2","Asia/Istanbul"}, +{"Jakarta","Indonesia","GMT+7","Asia/Jakarta"}, +{"Ambon","Indonesia","GMT+1","Asia/Jayapura"}, +{"Jerusalem","Israel","GMT+2","Asia/Jerusalem"}, +{"Kabul","Afghanistan","GMT+4:30","Asia/Kabul"}, +{"Kamchatka","Russia ","GMT+12","Asia/Kamchatka"}, +{"Petropavlovsk-Kamchatskiy","Russia ","GMT+12","Asia/Kamchatka"}, +{"Islamabad","Pakistan","GMT+5","Asia/Karachi"}, +{"Karachi","Pakistan","GMT+5","Asia/Karachi"}, +{"Kathmandu","Nepal","GMT+5:45","Asia/Kathmandu"}, +{"Chennai","India","GMT+5:30","Asia/Kolkata"}, +{"Delhi","India","GMT+5:30","Asia/Kolkata"}, +{"Kolkata","India","GMT+5:30","Asia/Kolkata"}, +{"Mumbai","India","GMT+5:30","Asia/Kolkata"}, +{"New Delhi","India","GMT+5:30","Asia/Kolkata "}, +{"Krasnoyarsk","Russia","GMT+7","Asia/Krasnoyarsk"}, +{"Kuala Lumpur","Malaysia","GMT+8","Asia/Kuala_Lumpur"}, +{"Kuwait","Kuwait","GMT+3","Asia/Kuwait"}, +{"Macau","China","GMT+8","Asia/Macau"}, +{"Magadan","Russia","GMT+11","Asia/Magadan"}, +{"Denpasar","Indonesia","GMT+8","Asia/Makassar"}, +{"Manila","Philippines","GMT+8","Asia/Manila"}, +{"Muscat","Oman","GMT+4","Asia/Muscat"}, +{"Novokuznetsk","Russia","GMT+7","Asia/Novokuznetsk"}, +{"Novosibirsk","Russia","GMT+6","Asia/Novosibirsk"}, +{"Omsk","Russia","GMT+6","Asia/Omsk"}, +{"Phnom Penh ","Cambodia","GMT-5","Asia/Phnom_Penh"}, +{"Pyongyang","North Korea","GMT+9","Asia/Pyongyang"}, +{"Doha","Qatar","GMT+3","Asia/Qatar"}, +{"Rangoon","Burma","GMT+6:30","Asia/Rangoon"}, +{"Jeddah","Saudi Arabia","GMT+3","Asia/Riyadh"}, +{"Mecca","Saudi Arabia","GMT+3","Asia/Riyadh"}, +{"Riyadh","Saudi Arabia","GMT+3","Asia/Riyadh"}, +{"Yuzhno-Sakhalinsk","Russia","GMT+11","Asia/Sakhalin"}, +{"Seoul","Republic of Korea","GMT+9","Asia/Seoul"}, +{"Beijing","China","GMT+8","Asia/Shanghai"}, +{"Canton","China","GMT+8","Asia/Shanghai"}, +{"Longhua","China","GMT+8","Asia/Shanghai"}, +{"Shanghai","China","GMT+8","Asia/Shanghai"}, +{"Shenzhen","China","GMT+8","Asia/Shanghai"}, +{"Tientsin","China","GMT+8","Asia/Shanghai "}, +{"Singapore","Republic of Singapore","GMT+8","Asia/Singapore"}, +{"Taipei","Taiwan","GMT+8","Asia/Taipei"}, +{"Tashkent","Uzbekistan","GMT+5","Asia/Tashkent"}, +{"Tbilisi","Georgia","GMT+4","Asia/Tbilisi"}, +{"Tehran","Iran","GMT+3:30","Asia/Tehran"}, +{"Osaka","Japan","GMT+9","Asia/Tokyo"}, +{"Tokyo","Japan","GMT+9","Asia/Tokyo"}, +{"Ulan Bator","Mongolia","GMT+8","Asia/Ulan_Bator"}, +{"Khabarovsk","Russia","GMT+10","Asia/Vladivostok"}, +{"Vladivostok","Russia","GMT+10","Asia/Vladivostok"}, +{"Chita","Russia","GMT+9","Asia/Yakutsk"}, +{"Yakutsk","Russia","GMT+9","Asia/Yakutsk"}, +{"Chelyabinsk","Russia","GMT+5","Asia/Yekaterinburg"}, +{"Perm","Russia","GMT+5","Asia/Yekaterinburg"}, +{"Ufa","Bashkiriya","GMT+5","Asia/Yekaterinburg"}, +{"Yekaterinburg","Russia","GMT+5","Asia/Yekaterinburg"}, +{"Yerevan","Armenia","GMT+5","Asia/Yerevan"}, +{"Azores","Portugal","GMT-1","Atlantic/Azores"}, +{"Ponta Delgada","Portugal","GMT-1","Atlantic/Azores"}, +{"Canary Islands","Spain","GMT+0","Atlantic/Canary"}, +{"Reykjavik","Iceland","GMT+0","Atlantic/Reykjavik"}, +{"Grytviken","South Georgia","GMT-2","Atlantic/South_Georgia"}, +{"Adelaide","Australia","GMT+9:30","Australia/Adelaide"}, +{"Brisbane","Australia","GMT+10","Australia/Brisbane"}, +{"Canberra","Australia","GMT+10","Australia/Canberra"}, +{"Darwin","Australia","GMT+9:30","Australia/Darwin"}, +{"Hobart","Australia","GMT+10","Australia/Hobart"}, +{"Melbourne","Australia","GMT+10","Australia/Melbourne"}, +{"Victoria","Seychelles","GMT+4","Australia/Melbourne"}, +{"Perth","Australia","GMT+8","Australia/Perth"}, +{"Sydney","Australia","GMT+11","Australia/Sydney"}, +{"Austin","United States of America","GMT-6","CST6CDT"}, +{"Dallas","United States of America","GMT-6","CST6CDT"}, +{"Houston","United States of America","GMT-6","CST6CDT"}, +{"Memphis","United States of America","GMT-6","CST6CDT"}, +{"Milwaukee","United States of America","GMT-6","CST6CDT"}, +{"San Antonio","United States of America","GMT-6","CST6CDT"}, +{"Baltimore","United States of America","GMT-5","EST5EDT"}, +{"Boston","United States of America","GMT-5","EST5EDT"}, +{"Charlotte","United States of America","GMT-5","EST5EDT"}, +{"Cleveland","United States of America","GMT-5","EST5EDT"}, +{"Columbus","United States of America","GMT-5","EST5EDT"}, +{"Miami","United States of America","GMT-5","EST5EDT"}, +{"Ottawa","Canada","GMT-5","EST5EDT"}, +{"Philadelphia","United States of America","GMT-5","EST5EDT"}, +{"Amsterdam","Netherlands","GMT+1","Europe/Amsterdam"}, +{"Athens","Greece","GMT+2","Europe/Athens"}, +{"Belgrade","Serbia","GMT+1","Europe/Belgrade"}, +{"Berlin","Germany","GMT+1","Europe/Berlin"}, +{"Hamburg","Germany","GMT+1","Europe/Berlin"}, +{"Munich","Germany","GMT+1","Europe/Berlin"}, +{"Bratislava","Slovakia","GMT+2","Europe/Bratislava"}, +{"Brussels","Belgium","GMT+1","Europe/Brussels"}, +{"Bucharest","Romania","GMT+3","Europe/Bucharest"}, +{"Budapest","Hungary","GMT+1","Europe/Budapest"}, +{"Chisinau","Moldova","GMT+2","Europe/Chisinau"}, +{"Copenhagen","Denmark","GMT+1","Europe/Copenhagen"}, +{"Cork","Ireland","GMT+0","Europe/Dublin"}, +{"Dublin","Ireland","GMT+0","Europe/Dublin"}, +{"Helsinki","Finland","GMT+2","Europe/Helsinki"}, +{"Istanbul","Turkey","GMT+2","Europe/Istanbul"}, +{"Kaliningrad","Russia","GMT+2","Europe/Kaliningrad"}, +{"Kharkiv","Ukraine","GMT+2","Europe/Kiev"}, +{"Kiev","Ukraine","GMT+2","Europe/Kiev"}, +{"Lviv","Ukraine","GMT+2","Europe/Kiev"}, +{"Kyiv","Ukraine","GMT+2","Europe/Kiev "}, +{"Lisbon","Portugal","GMT+0","Europe/Lisbon"}, +{"Ljubljana","Slovakia","GMT+1","Europe/Ljubljana"}, +{"Cardiff","Wales","GMT+0","Europe/London"}, +{"Edinburgh","Scotland","GMT+0","Europe/London"}, +{"London","United Kingdom","GMT+0","Europe/London"}, +{"Luxembourg","Luxembourg","GMT+1","Europe/Luxembourg"}, +{"Barcelona","Spain","GMT+2","Europe/Madrid"}, +{"Madrid","Spain","GMT+2","Europe/Madrid"}, +{"Valletta","Malta","GMT+1","Europe/Malta"}, +{"Minsk","Belarus","GMT+2","Europe/Minsk"}, +{"Izhevsk","Russia","GMT+4","Europe/Moscow"}, +{"Moscow","Russia","GMT+3","Europe/Moscow"}, +{"St. Petersburg","Russia","GMT+3","Europe/Moscow"}, +{"Geneva","Switzerland","GMT+1","Europe/Paris"}, +{"Paris","France","GMT+1","Europe/Paris"}, +{"Trehet","France","GMT+1","Europe/Paris "}, +{"Podgorica","Montenegro","GMT+1","Europe/Podgorica"}, +{"Prague","Czech Republic","GMT+1","Europe/Prague"}, +{"Riga","Latvia","GMT+2","Europe/Riga"}, +{"Bari","Italy","GMT+1","Europe/Rome"}, +{"Bologna","Italy","GMT+1","Europe/Rome"}, +{"Catanzaro","Italy","GMT+1","Europe/Rome"}, +{"Crotone","Italy","GMT+1","Europe/Rome"}, +{"Florence","Italy","GMT+1","Europe/Rome"}, +{"Genoa","Italy","GMT+1","Europe/Rome"}, +{"Messina","Italy","GMT+1","Europe/Rome"}, +{"Milan","Italy","GMT+1","Europe/Rome"}, +{"Naples","Italy","GMT+1","Europe/Rome"}, +{"Palermo","Italy","GMT+1","Europe/Rome"}, +{"Rome","Italy","GMT+1","Europe/Rome"}, +{"Turin","Italy","GMT+1","Europe/Rome"}, +{"Verona","Italy","GMT+1","Europe/Rome"}, +{"Samara","Russia","GMT+4","Europe/Samara"}, +{"San Marino","Italy","GMT+1","Europe/San_Marino"}, +{"Skopje","Macedonia","GMT+1","Europe/Skopje"}, +{"Sofia ","Bulgaria","GMT+3","Europe/Sofia"}, +{"Stockholm","Sweden","GMT+2","Europe/Stockholm"}, +{"Tallinn","Estonia","GMT+2","Europe/Tallinn"}, +{"Vaduz","Liechtenstein","GMT+1","Europe/Vaduz"}, +{"Vienna","Austria","GMT+1","Europe/Vienna"}, +{"Vilnius","Lithuania","GMT+3","Europe/Vilnius"}, +{"Volgograd","Russia","GMT+4","Europe/Volgograd"}, +{"Warsaw","Poland","GMT+2","Europe/Warsaw"}, +{"Zagreb","Croatia","GMT+1","Europe/Zagreb"}, +{"Bern","Switzerland","GMT+1","Europe/Zurich"}, +{"Naters","Switzerland","GMT+1","Europe/Zurich"}, +{"Zurich","Switzerland","GMT+1","Europe/Zurich"}, +{"Antananarivo","Madagascar","GMT+3","Indian/Antananarivo"}, +{"Diego Garcia","United Kingdom","GMT+5","Indian/Chagos "}, +{"Male","Maldives","GMT+5","Indian/Maldives"}, +{"Port Louis","Mauritius","GMT+4","Indian/Mauritius"}, +{"Saint-Denis","Reunion Island","GMT+4","Indian/Reunion"}, +{"Calgary","Canada","GMT-7","MST7MDT"}, +{"El Paso","United States of America","GMT-7","MST7MDT"}, +{"Auckland","New Zealand","GMT+12","Pacific/Auckland"}, +{"Wellington","New Zealand","GMT+12","Pacific/Auckland"}, +{"Easter Island","Chile","GMT-6","Pacific/Easter"}, +{"Suva","Fiji","GMT+12","Pacific/Fiji"}, +{"Galapagos Islands","Ecuador","GMT-7","Pacific/Galapagos"}, +{"Guam","United States of America","GMT+10","Pacific/Guam"}, +{"Hawaii","United States of America","GMT-10","Pacific/Honolulu"}, +{"Honolulu","United States of America","GMT-10","Pacific/Honolulu"}, +{"Midway Atoll","United States of America","GMT-11","Pacific/Midway"}, +{"Noumea","New Caledonia","GMT+11","Pacific/Noumea"}, +{"Pago Pago","Independent State of Samoa","GMT-11","Pacific/Pago_Pago"}, +{"Tahiti","French Polynesia","GMT-10","Pacific/Tahiti"}, +{"Tarawa","Kiribati","GMT+12","Pacific/Tarawa"}, +{"Nuku'alofa","Tonga","GMT+13","Pacific/Tongatapu"}, +{"Las Vegas","United States of America","GMT-8","PST8PDT"}, +{"Portland","United States of America","GMT-8","PST8PDT"}, +{"San Diego","United States of America","GMT-8","PST8PDT"}, +{"San Jose","United States of America","GMT-8","PST8PDT"}, +{"Seattle","United States of America","GMT-8","PST8PDT"}, +{"Washington, D.C.","United States of America","GMT-5","EST5EDT"}, +{NULL, NULL, NULL, NULL} +}; + +#ifndef SECSPERHOUR +#define SECSPERHOUR 3600 //(SECSPERMIN * MINSPERHOUR) +#endif /* !defined SECSPERHOUR */ + +#ifndef SECSPERDAY +#define SECSPERDAY 86400 //(SECSPERHOUR * HOURSPERDAY) +#endif /* !defined SECSPERDAY */ + + +time_t cals_mktime(struct tm *date_time); +struct tm *cals_tmtime(time_t *sec); +struct tm* cals_tmtime_r(time_t *ttTime, struct tm *tmTime); + +#endif /* __CALENDAR_SVC_TZ_UTILS_H__ */ diff --git a/src/cals-utils.c b/src/cals-utils.c new file mode 100755 index 0000000..b1fe7a6 --- /dev/null +++ b/src/cals-utils.c @@ -0,0 +1,768 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include + +#include "cals-typedef.h" +#include "cals-utils.h" +#include "cals-recurrence-utils.h" +#include "cals-db.h" +#include "cals-db-info.h" +#include "cals-internal.h" +#include "cals-tz-utils.h" +#include "cals-sqlite.h" + +extern sqlite3* calendar_db_handle; + +typedef enum +{ + CAL_SCH_TERM_ONE_DAY, + CAL_SCH_TERM_OVER_2_DAYS, + CAL_SCH_TERM_OVER_7_DAYS, + CAL_SCH_TERM_OVER_1_MONTH, + CAL_SCH_TERM_OVER_1_YEAR, + CAL_SCH_TERM_ERROR +} __cal_sch_term_status_t; + +static cal_month_tab g_month_day[] = { {1,31}, {2,28}, {3,31}, {4,30}, {5,31}, {6,30}, {7,31}, {8,31}, {9,30}, {10,31}, {11,30}, {12,31} }; + +static const char *CALS_NOTI_EVENT_CHANGED="/opt/data/calendar-svc/.CALENDAR_SVC_EVENT_CHANGED"; +static const char *CALS_NOTI_TODO_CHANGED="/opt/data/calendar-svc/.CALENDAR_SVC_TODO_CHANGED"; +static const char *CALS_NOTI_CALENDAR_CHANGED="/opt/data/calendar-svc/.CALENDAR_SVC_CALENDAR_CHANGED"; + +static int transaction_cnt = 0; + +static bool event_change=false; +static bool todo_change=false; +static bool calendar_change=false; + +static inline void _cals_notify_event_change(void) +{ + int fd = open(CALS_NOTI_EVENT_CHANGED, O_TRUNC | O_RDWR); + if (0 <= fd) { + close(fd); + event_change = false; + } +} + +static inline void _cals_notify_todo_change(void) +{ + int fd = open(CALS_NOTI_TODO_CHANGED, O_TRUNC | O_RDWR); + if (0 <= fd) { + close(fd); + todo_change = false; + } +} + +static inline void _cals_notify_calendar_change(void) +{ + int fd = open(CALS_NOTI_CALENDAR_CHANGED, O_TRUNC | O_RDWR); + if (0 <= fd) { + close(fd); + calendar_change = false; + } +} + +const char* cals_noti_get_file_path(int type) +{ + const char *noti; + switch (type) + { + case CALS_NOTI_TYPE_EVENT: + noti = CALS_NOTI_EVENT_CHANGED; + break; + case CALS_NOTI_TYPE_TODO: + noti = CALS_NOTI_TODO_CHANGED; + break; + case CALS_NOTI_TYPE_CALENDAR: + noti = CALS_NOTI_CALENDAR_CHANGED; + break; + default: + ERR("The type(%d) is not supported", type); + return NULL; + } + + return noti; +} + +int cals_notify(cals_noti_type type) +{ + if (0 < transaction_cnt) { + switch (type) { + case CALS_NOTI_TYPE_EVENT: + event_change = true; + break; + case CALS_NOTI_TYPE_TODO: + todo_change = true; + break; + case CALS_NOTI_TYPE_CALENDAR: + calendar_change = true; + break; + default: + ERR("The type(%d) is not supported", type); + return CAL_ERR_ARG_INVALID; + } + return CAL_SUCCESS; + } + + switch(type) { + case CALS_NOTI_TYPE_EVENT: + _cals_notify_event_change(); + break; + case CALS_NOTI_TYPE_TODO: + _cals_notify_todo_change(); + break; + case CALS_NOTI_TYPE_CALENDAR: + _cals_notify_calendar_change(); + break; + default: + ERR("The type(%d) is not supported", type); + return CAL_ERR_ARG_INVALID; + } + + return CAL_SUCCESS; +} + +#define CAL_COMMIT_TRY_MAX 500000 +int cals_begin_trans(void) +{ + if(transaction_cnt <= 0) + { + int ret, progress; + + progress = 100000; + ret = cals_query_exec("BEGIN IMMEDIATE TRANSACTION"); + while(CAL_ERR_DB_LOCK == ret && progress < CAL_COMMIT_TRY_MAX) { + usleep(progress); + ret = cals_query_exec("BEGIN IMMEDIATE TRANSACTION"); + progress *= 2; + } + retvm_if(CAL_SUCCESS != ret, ret, "cals_query_exec() Failed(%d)", ret); + + transaction_cnt = 0; + } + transaction_cnt++; + CALS_DBG("transaction_cnt : %d", transaction_cnt); + + return CAL_SUCCESS; +} + + +static inline void _cals_cancel_changes(void) +{ + event_change = false; + calendar_change = false; + todo_change = false; +} + + +int cals_end_trans(bool is_success) +{ + int ret; + int progress = 0; + + transaction_cnt--; + + if (0 != transaction_cnt) { + CALS_DBG("transaction_cnt : %d", transaction_cnt); + return CAL_SUCCESS; + } + + if (false == is_success) { + _cals_cancel_changes(); + ret = cals_query_exec("ROLLBACK TRANSACTION"); + return CAL_SUCCESS; + } + + progress = 400000; + ret = cals_query_exec("COMMIT TRANSACTION"); + while (CAL_ERR_DB_LOCK == ret && progress < CAL_COMMIT_TRY_MAX) { + usleep(progress); + ret = cals_query_exec("COMMIT TRANSACTION"); + progress *= 2; + } + if (CAL_SUCCESS != ret) { + int tmp_ret; + ERR("cals_query_exec() Failed(%d)", ret); + _cals_cancel_changes(); + tmp_ret = cals_query_exec("ROLLBACK TRANSACTION"); + warn_if(CAL_SUCCESS != tmp_ret, "cals_query_exec(ROLLBACK) Failed(%d).", tmp_ret); + return ret; + } + if (event_change) _cals_notify_event_change(); + if (todo_change) _cals_notify_todo_change(); + if (calendar_change) _cals_notify_calendar_change(); + + return CAL_SUCCESS; +} + +API int calendar_svc_begin_trans(void) +{ + CALS_FN_CALL; + return cals_begin_trans(); +} + +API int calendar_svc_end_trans() +{ + CALS_FN_CALL; + return cals_end_trans(true); +} + + +int cal_db_service_get_day_count_in_month(int input_year, int input_mon) +{ + input_year = input_year + BENCHMARK_YEAR; + input_mon = input_mon + 1; + + if ((input_year % 4) == 0) { + if ((input_year % 100) == 0) { + if ((input_year % 400) == 0) + g_month_day[1].day = 29; + else + g_month_day[1].day = 28; + } else { + g_month_day[1].day = 29; + } + } else { + g_month_day[1].day = 28; + } + + return g_month_day[(input_mon - 1)].day; +} + + +static bool cal_get_day_count_in_month(int year, int month, int *count, int *error_code) +{ + assert((count != NULL) && (error_code != NULL)); + + if(year < CAL_YEAR_MIN || CAL_YEAR_MAX < year) { + ERR("year is invalid."); + *error_code = CAL_ERR_ARG_INVALID; + return false; + } + + if(month < CAL_MONTH_CNT_MIN || CAL_MONTH_CNT_MAX < month) { + ERR("month is invalid."); + *error_code = CAL_ERR_ARG_INVALID; + return false; + } + + year = year - BENCHMARK_YEAR; + month = month - 1; + + *count = cal_db_service_get_day_count_in_month(year, month); + return true; +} + +void cal_db_service_set_repeat_end_date(cal_sch_full_t *sch_record) +{ + int i = 0; + struct tm start_tm={0}; + struct tm end_tm={0}; + struct tm next_valid_start_tm={0}; + struct tm next_valid_end_tm={0}; + cal_date_param_t cal_date_param; + memset(&cal_date_param, 0x00, sizeof(cal_date_param_t)); + + start_tm.tm_year = TM_YEAR_MIN; + start_tm.tm_mon = MONTH_MIN; + start_tm.tm_mday = MONTH_DAY_MIN; + + end_tm.tm_year = TM_YEAR_MAX; + end_tm.tm_mon = MONTH_MAX; + end_tm.tm_mday = MONTH_DAY_MAX; + + sch_record->repeat_end_date.tm_year = TM_YEAR_MAX-1; + sch_record->repeat_end_date.tm_mon = MONTH_MAX; + sch_record->repeat_end_date.tm_mday = MONTH_DAY_MAX; + + cal_service_set_date_param(&cal_date_param, sch_record); + + for(i = 0;irepeat_occurrences; i++) + { + cal_db_service_get_next_valid_exception_time(sch_record, + &cal_date_param,NULL,&start_tm,&end_tm,&next_valid_start_tm,&next_valid_end_tm); + } + + memcpy(&sch_record->repeat_end_date, &next_valid_start_tm, sizeof(struct tm)); + ERR("sch_record->repeat_end_date:%d-%d-%d",sch_record->repeat_end_date.tm_year,sch_record->repeat_end_date.tm_mon,sch_record->repeat_end_date.tm_mday); +} + + +bool cal_db_get_text_from_stmt(sqlite3_stmt *stmt,char** p_str_dst,int column) +{ + char *str_temp = NULL; + int str_len = 0; + + str_temp = (char *)sqlite3_column_text(stmt, column); + str_len = sqlite3_column_bytes(stmt, column); + + if(0 == str_len) + { + *p_str_dst = NULL; + return true; + } + + CAL_FREE(*p_str_dst); + + + *p_str_dst = (char*)malloc(str_len+1); + retvm_if(NULL == *p_str_dst, false, "failed to malloc str_dst"); + + memcpy(*p_str_dst,str_temp,str_len); + (*p_str_dst)[str_len] = '\0'; + + return true; +} + +bool cal_db_get_blob_from_stmt(sqlite3_stmt *stmt,struct tm* p_tm,int column) +{ + struct tm* temp = NULL; + + if(NULL == p_tm) + { + return false; + } + + temp = (struct tm*)sqlite3_column_blob(stmt, column); + if(NULL == temp) + { + return false; + } + + memcpy(p_tm,temp,sizeof(struct tm)); + return true; +} + + +bool cal_db_service_convert_stmt_to_tz_info(sqlite3_stmt *stmt,cal_timezone_t * tz_info) +{ + CALS_FN_CALL; + + int count = 0; + + tz_info->index = sqlite3_column_int(stmt, count++); + tz_info->tz_offset_from_gmt = sqlite3_column_int(stmt, count++); + + cal_db_get_text_from_stmt(stmt,&(tz_info->standard_name),count++); + + tz_info->std_start_month = sqlite3_column_int(stmt, count++); + tz_info->std_start_position_of_week = sqlite3_column_int(stmt, count++); + tz_info->std_start_day = sqlite3_column_int(stmt, count++); + tz_info->std_start_hour = sqlite3_column_int(stmt, count++); + tz_info->standard_bias = sqlite3_column_int(stmt, count++); + + cal_db_get_text_from_stmt(stmt,&(tz_info->day_light_name),count++); + + tz_info->day_light_start_month = sqlite3_column_int(stmt, count++); + tz_info->day_light_start_position_of_week = sqlite3_column_int(stmt, count++); + tz_info->day_light_start_day = sqlite3_column_int(stmt, count++); + tz_info->day_light_start_hour = sqlite3_column_int(stmt, count++); + tz_info->day_light_bias = sqlite3_column_int(stmt, count++); + + return true; +} + + +bool cal_db_service_convert_stmt_to_list_field_record(sqlite3_stmt *stmt,cal_sch_full_t *sch_record, bool is_utc) +{ + assert(sch_record != NULL); + int i = 0; + long int temp = 0; + + sch_record->index = sqlite3_column_int(stmt, i++); + cal_db_get_text_from_stmt(stmt,&(sch_record->summary),i++); + cal_db_get_text_from_stmt(stmt,&(sch_record->location),i++); + + sch_record->all_day_event = sqlite3_column_int(stmt, i++); + + temp = sqlite3_column_int(stmt, i++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&temp),&(sch_record->start_date_time)); + temp = sqlite3_column_int(stmt, i++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&temp),&(sch_record->end_date_time)); + + sch_record->repeat_term = sqlite3_column_int(stmt, i++); + + sch_record->week_start = sqlite3_column_int(stmt, i++); + cal_db_get_text_from_stmt(stmt,&(sch_record->week_flag),i++); + + sch_record->calendar_id = sqlite3_column_int(stmt, i++); + + return true; + +} + +bool cal_db_service_convert_stmt_to_month_field_record(sqlite3_stmt *stmt,int is_repeat,cal_sch_full_t *sch_record, bool is_utc) +{ + assert(sch_record != NULL); + int i = 0; + long int temp = 0; + + sch_record->index = sqlite3_column_int(stmt, i++); + sch_record->all_day_event = sqlite3_column_int(stmt, i++); + + temp = sqlite3_column_int(stmt, i++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&temp),&(sch_record->start_date_time)); + temp = sqlite3_column_int(stmt, i++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&temp),&(sch_record->end_date_time)); + + if(is_repeat) + { + sch_record->repeat_term = sqlite3_column_int(stmt, i++); + sch_record->repeat_interval = sqlite3_column_int(stmt, i++); + sch_record->repeat_occurrences = sqlite3_column_int(stmt, i++); + temp = sqlite3_column_int(stmt, i++); + cal_db_service_copy_struct_tm((struct tm*)cals_tmtime(&temp),&(sch_record->repeat_end_date)); + sch_record->week_start = sqlite3_column_int(stmt, i++); + cal_db_get_text_from_stmt(stmt,&(sch_record->week_flag),i++); + sch_record->day_date = sqlite3_column_int(stmt, i++); + sch_record->timezone = sqlite3_column_int(stmt, i++); + cal_db_get_text_from_stmt(stmt,&(sch_record->tz_name),i++); + } + + return true; + +} + + +#define MONTH_MAX 11 + +// week day from 0--6 +#define MAX_WEEK_DAY 7 + +#define MONTH_DAY_MAX 31 +#define MONTH_DAY_MIN 1 + +#define MONTH_MIN 0 + +#define TM_YEAR_MIN 0 +#define TM_YEAR_MAX 138 +#define TM_YEAR_OFFSET 1900 + +#define TIME_HOUR_MAX_12 12 +#define TIME_HOUR_MAX_24 23 + +#define TIME_ZONE_COUNT 28 + +typedef enum +{ + OEG_CALENDAR_ITEM_MEETING_CATEGORY = 0, + OEG_CALENDAR_ITEM_ATTENDEE_LIST +}OEG_CALENDAR_ITEM_TYPE; + + + static bool +__cal_db_service_get_next_month_first_day(struct tm* tm) +{ + tm->tm_mon++; + tm->tm_mday = MONTH_DAY_MIN; + + return TRUE; + +} + + static bool +__cal_db_service_get_next_year_first_day(struct tm* tm) +{ + tm->tm_year++; + tm->tm_mon = MONTH_MIN; + tm->tm_mday = MONTH_DAY_MIN; + + return TRUE; + +} + + bool +cal_db_service_get_tomorrow(struct tm* tm) +{ + int day_count = 0; + int error_code = 0; + + int year = tm->tm_year + TM_YEAR_OFFSET; + int month = tm->tm_mon + 1; + + cal_get_day_count_in_month(year, month, &day_count, &error_code); + + if (tm->tm_mday < day_count) + { + tm->tm_mday++; + } + else + { + if ( tm->tm_mon < MONTH_MAX) + { + __cal_db_service_get_next_month_first_day(tm); + } + else + { + // to next year the first day + __cal_db_service_get_next_year_first_day(tm); + } + } + + return TRUE; + +} + + bool +cal_db_service_get_next_month(struct tm* tm) +{ + if (tm->tm_mon == 11) + { + if (tm->tm_year == TM_YEAR_MAX-1) + { + tm->tm_mday = 31; + } + else + { + tm->tm_mon = 0; + tm->tm_year ++; + } + } + else + { + tm->tm_mon ++; + } + + return true; +} + +void cal_db_service_copy_struct_tm(const struct tm *tm_src, struct tm *tm_des) +{ + ret_if(NULL == tm_src); + ret_if(NULL == tm_des); + + tm_des->tm_sec = tm_src->tm_sec; + tm_des->tm_min = tm_src->tm_min; + tm_des->tm_hour = tm_src->tm_hour; + tm_des->tm_mday = tm_src->tm_mday; + tm_des->tm_wday = tm_src->tm_wday; + + tm_des->tm_mon = tm_src->tm_mon; + tm_des->tm_year = tm_src->tm_year; + + tm_des->tm_yday = tm_src->tm_yday; + tm_des->tm_isdst = tm_src->tm_isdst; +} + + +bool cal_db_service_get_current_time(struct tm * time_date) +{ + assert(time_date != NULL); + + time_t t = time(NULL); + + tzset(); + localtime_r(&t,time_date); + + return TRUE; +} + + + void +cal_db_service_set_sch_weekflag(struct tm* date_time, char *week_flag) +{ + GDate cur_date={0,}; + + g_date_set_dmy(&cur_date, (GDateDay) date_time->tm_mday, (GDateMonth) ( + date_time->tm_mon + 1), (GDateYear) (date_time->tm_year + TM_YEAR_OFFSET)); + + date_time->tm_wday = g_date_get_weekday (&cur_date); + + switch (date_time->tm_wday) + { + case 7: + memcpy(week_flag,"1000000",DAY_OF_A_WEEK); + break; + case 1: + memcpy(week_flag,"0100000",DAY_OF_A_WEEK); + break; + case 2: + memcpy(week_flag,"0010000",DAY_OF_A_WEEK); + break; + case 3: + memcpy(week_flag,"0001000",DAY_OF_A_WEEK); + break; + case 4: + memcpy(week_flag,"0000100",DAY_OF_A_WEEK); + break; + case 5: + memcpy(week_flag,"0000010",DAY_OF_A_WEEK); + break; + case 6: + memcpy(week_flag,"0000001",DAY_OF_A_WEEK); + break; + default: + + break; + } + +} + + +bool cal_vcalendar_convert_tm_to_vdata_str(const struct tm *tm, char *utc_str) +{ + + memset(utc_str, 0, 17); + + sprintf(utc_str, "%04ld%02d%02dT%02d%02d%02dZ", + tm->tm_year + BENCHMARK_YEAR, + tm->tm_mon +1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + + return true; + +} + +void cal_vcalendar_convert_utc_str_to_tm(const char *szText, struct tm *tm) +{ + assert((szText != NULL) && (tm != NULL)); + + char szBuff[8]; + + // struct tm tm; + memset(tm, 0, sizeof(struct tm)); + + // year, month, day + memcpy(szBuff, &(szText[0]), 4); + szBuff[4] = '\0'; + tm->tm_year = atol(szBuff) - BENCHMARK_YEAR; + if ((tm->tm_year > (CAL_YEAR_MAX - BENCHMARK_YEAR)) || (tm->tm_year < (CAL_YEAR_MIN - BENCHMARK_YEAR))) + { + tm->tm_year = (CAL_YEAR_MAX - BENCHMARK_YEAR); + } + + memcpy(szBuff, &(szText[4]), 2); + szBuff[2] = '\0'; + tm->tm_mon = atol(szBuff)-1; + if ((tm->tm_mon > 11) || (tm->tm_mon < 0)) + { + tm->tm_mon = 11; + } + + memcpy(szBuff, &(szText[6]), 2); + szBuff[2] = '\0'; + tm->tm_mday = atol(szBuff); + if ((tm->tm_mday > 31) || (tm->tm_mday < 1)) + { + tm->tm_mday = 31; + } + + // hour, minute, second + memcpy(szBuff, &(szText[9]), 2); + szBuff[2] = '\0'; + tm->tm_hour = atol(szBuff); + if ((tm->tm_hour > 23) || (tm->tm_hour < 0)) + { + tm->tm_hour = 23; + } + + memcpy(szBuff, &(szText[11]), 2); + szBuff[2] = '\0'; + tm->tm_min = atol(szBuff); + if ((tm->tm_min > 59) || (tm->tm_min < 0)) + { + tm->tm_min = 59; + } + + memcpy(szBuff, &(szText[13]), 2); + szBuff[2] = '\0'; + tm->tm_sec = atol(szBuff); + if ((tm->tm_sec > 59) || (tm->tm_sec < 0)) + { + tm->tm_sec = 59; + } + + CALS_DBG( "\n-------------------cal_vcalendar_convert_utc_str_to_tm year is %d, month is %d, day is %d, hour is %d, min is %d, sec is %d--------------------\n", + tm->tm_year,tm->tm_mon,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); +} + + bool +cal_util_convert_query_string(const char *src, char *dst) +{ + int i = 0; + int j = 0; + int nSrc = 0; + + if (src == NULL || dst == NULL) + { + return FALSE; + } + + nSrc = strlen(src); + + for(i = 0; i < nSrc; ++i) + { + if (src[i] == '\'') + { + dst[j++] = src[i]; + dst[j++] = src[i]; + } + else if (src[i] == '%') + { + dst[j++] = src[i]; + dst[j++] = src[i]; + } + else + { + dst[j++] = src[i]; + } + } + dst[j] = '\0'; + + return TRUE; +} + +cal_iter* cals_get_updated_list(int type, int calendar_id, time_t timestamp) +{ + cal_iter *iter; + sqlite3_stmt *stmt; + char query[CALS_SQL_MIN_LEN]; + + retvm_if(timestamp < 0, NULL, "timestamp(%ld) is Invalid", timestamp); + + iter = calloc(1, sizeof(cal_iter)); + retvm_if(NULL == iter, NULL, "calloc() Failed"); + + if (calendar_id) + sprintf(query,"SELECT * FROM %s WHERE type = %d AND last_modified_time > %ld AND calendar_id = %d", + CALS_TABLE_SCHEDULE, type, timestamp, calendar_id); + else + sprintf(query,"SELECT * FROM %s WHERE type = %d AND last_modified_time > %ld", + CALS_TABLE_SCHEDULE, type, timestamp); + + stmt = cals_query_prepare(query); + if (NULL == stmt) { + free(iter); + ERR("cals_query_prepare() Failed"); + return NULL; + } + + iter->stmt = stmt; + if (CAL_EVENT_TODO_TYPE == type) + iter->i_type = CAL_STRUCT_TYPE_TODO; + else + iter->i_type = CAL_STRUCT_TYPE_SCHEDULE; + + return iter; +} + diff --git a/src/cals-utils.h b/src/cals-utils.h new file mode 100755 index 0000000..7fc965b --- /dev/null +++ b/src/cals-utils.h @@ -0,0 +1,115 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __CALENDAR_SVC_UTILS_H__ +#define __CALENDAR_SVC_UTILS_H__ + +#include +#include +#include +#include +#include "db-util.h" +#include + +//SQL operation type. May be used for other usage. +typedef enum +{ + CAL_SQL_TYPE_INSERT = 0, + CAL_SQL_TYPE_UPDATE +} cal_sql_type_t; + + +/** +* @enum __cal_sch_field_t +* This enumeration Schedule database field index. +*/ +typedef enum +{ + CAL_SCH_FIELD_INDEX = 0, /**< This is an invalid type. */ + CAL_SCH_FIELD_TYPE, /**< This is an calendar type. */ + CAL_SCH_FIELD_CATEGORY, /**< This is an schedule category type. */ + CAL_SCH_FIELD_SUMMARY, /**< This is an schedule summary */ + CAL_SCH_FIELD_DESCRIPTION, /**< This is description */ + CAL_SCH_FIELD_LOCATION, /**< This is location */ + CAL_SCH_FIELD_ALL_DAY_EVENT, /**< This is all day event */ + CAL_SCH_FIELD_START_DATE_TIME, /**< This is start date time */ + CAL_SCH_FIELD_END_DATE_TIME, /**< This is end date time */ + CAL_SCH_FIELD_ALARM_TIME, /**< This is alarm time */ + CAL_SCH_FIELD_REMIND_TICK, /**< This is remind tick */ + CAL_SCH_FIELD_REMIND_TICK_UNIT, /**< This is remind tick unit */ + CAL_SCH_FIELD_ALARM_ID, /**< This is alarm id */ + CAL_SCH_FIELD_REPEAT_TERM, /**< This is repeat term */ + CAL_SCH_FIELD_REPEAT_INTERVAL, /**< Interval of repeat term */ + CAL_SCH_FIELD_REPEAT_END_DATE, /**< This is repead end date */ + CAL_SCH_FIELD_REPEAT_SUN_MOON, /**< Using sun or lunar calendar */ + CAL_SCH_FIELD_REPEAT_WEEK_START, /**< Start day of a week */ + CAL_SCH_FIELD_REPEAT_WEEK_FLAG, /**< Indicate which day is select in a week */ + CAL_SCH_FIELD_REPEAT_DAY_DATE, /**< 0- for weekday(sun,mon,etc.) , 1 - for specific day(1,2.. Etc) */ + CAL_SCH_FIELD_MISSED, /**< This is missed flag */ + CAL_SCH_FIELD_CALENDAR_TYPE, /**< Calendar type */ + CAL_SCH_FIELD_TIME_ZOON, /**< This is time zoon of calendar event */ + CAL_SCH_FIELD_DST, /**< This is dst of an event*/ + + CAL_SCH_FIELD_CNT_MAX /**< This is count max */ +} __cal_sch_field_t; + + +typedef struct +{ + int mname; // month + int day; // day count +} cal_month_tab; + +bool cal_db_get_text_from_stmt(sqlite3_stmt * stmt,char * * p_str_dst,int column); + +bool cal_db_get_blob_from_stmt(sqlite3_stmt * stmt,struct tm * p_tm,int column); + +bool cal_db_service_convert_stmt_to_tz_info(sqlite3_stmt *stmt,cal_timezone_t * tz_info); + +int cal_db_service_get_day_count_in_month(int input_year, int input_mon); + +bool cal_db_service_get_current_time(struct tm * time_date); + +bool cal_db_service_get_tomorrow(struct tm* tm); + +bool cal_db_service_get_next_month(struct tm* tm); + +void cal_db_service_copy_struct_tm(const struct tm *tm_src, struct tm *tm_des); + +void cal_db_service_set_sch_weekflag(struct tm* date_time, char *week_flag); + +bool cal_vcalendar_convert_tm_to_vdata_str(const struct tm * tm, char * utc_str); + +void cal_vcalendar_convert_utc_str_to_tm(const char *szText, struct tm * tm); + +bool cal_util_convert_query_string(const char *src, char *dst); + +void cal_db_service_set_repeat_end_date(cal_sch_full_t *sch_record); + +bool cal_db_service_convert_stmt_to_list_field_record(sqlite3_stmt *stmt,cal_sch_full_t *sch_record, bool is_utc); +bool cal_db_service_convert_stmt_to_month_field_record(sqlite3_stmt *stmt,int is_repeat,cal_sch_full_t *sch_record, bool is_utc); + +cal_iter* cals_get_updated_list(int type, int calendar_id, time_t timestamp); + +int cals_notify(cals_noti_type operation_type); +int cals_begin_trans(void); +int cals_end_trans(bool is_success); +const char* cals_noti_get_file_path(int type); + + +#endif /* __CALENDAR_SVC_UTILS_H__ */ diff --git a/test/Makefile b/test/Makefile new file mode 100755 index 0000000..7bd5133 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,30 @@ +CC = gcc + +REQUIRED_PKG = calendar-service +CFLAGS = -g -Wall +LDFLAGS = # -L../ -lefence -pthread +ifdef REQUIRED_PKG + CFLAGS += `pkg-config --cflags $(REQUIRED_PKG)` + LDFLAGS += `pkg-config --libs $(REQUIRED_PKG)` +endif + +SRCS = calendar-test.c schedule-test.c +TIMESRC = timetest.c +OBJECTS = $(SRCS:.c=.o) +TIMEOBJ = $(TIMESRC:.c=.o) +TARGETS = $(OBJECTS:.o=) +#A:.c=.o //A안에 있는 .c를 .o로 바꿔라 + + +all: $(OBJECTS) $(TARGETS) +#-mv test1 testlocal /usr/ + +$(TARGETS): $(TIMEOBJ) +$(TIMEOBJ): timetest.h + +% : %.o + $(CC) -o $@ $< $(TIMEOBJ) $(LDFLAGS) + +clean: + rm -rf $(OBJECTS) $(TARGETS) $(TIMEOBJ) + diff --git a/test/calendar-test.c b/test/calendar-test.c new file mode 100755 index 0000000..c56fa34 --- /dev/null +++ b/test/calendar-test.c @@ -0,0 +1,113 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include "test-log.h" + +static inline int insert_calendar1() +{ + int ret; + cal_struct *calendar = NULL; + + calendar = calendar_svc_struct_new(CAL_STRUCT_CALENDAR); + + calendar_svc_struct_set_int(calendar, CAL_TABLE_INT_ACCOUNT_ID, 1); + calendar_svc_struct_set_int(calendar, CAL_TABLE_INT_VISIBILITY, 1); + calendar_svc_struct_set_str(calendar, CAL_TABLE_TXT_NAME, "Test Calendar1"); + calendar_svc_struct_set_str(calendar, CAL_TABLE_TXT_DESCRIPTION, "Event only calendar"); + calendar_svc_struct_set_int(calendar, CAL_TABLE_INT_STORE_TYPE, CALS_CALENDAR_TYPE_EVENT); + + ret = calendar_svc_insert(calendar); + calendar_svc_struct_free(&calendar); + + if (ret < CAL_SUCCESS) { + ERR("calendar_svc_insert() Failed(%d)", ret); + return -1; + } else { + DBG("calendar_svc_insert() return %d", ret); + return ret; + } +} + + +static inline int insert_calendar2() +{ + int ret; + cal_struct *calendar = NULL; + + calendar = calendar_svc_struct_new(CAL_STRUCT_CALENDAR); + + calendar_svc_struct_set_int(calendar, CAL_TABLE_INT_ACCOUNT_ID, 1); + calendar_svc_struct_set_int(calendar, CAL_TABLE_INT_VISIBILITY, 1); + calendar_svc_struct_set_str(calendar, CAL_TABLE_TXT_NAME, "Test Calendar2"); + calendar_svc_struct_set_str(calendar, CAL_TABLE_TXT_DESCRIPTION, "Event and Todo calendar"); + calendar_svc_struct_set_int(calendar, CAL_TABLE_INT_STORE_TYPE, CALS_CALENDAR_TYPE_EVENT|CALS_CALENDAR_TYPE_TODO); + + ret = calendar_svc_insert(calendar); + calendar_svc_struct_free(&calendar); + + if (ret < CAL_SUCCESS) { + ERR("calendar_svc_insert() Failed(%d)", ret); + return -1; + } else { + DBG("calendar_svc_insert() return %d", ret); + return ret; + } +} + +static inline void get_calendar(int index) +{ + int ret; + cal_struct *calendar = NULL; + + ret = calendar_svc_get(CAL_STRUCT_CALENDAR, index, NULL, &calendar); + if (ret < CAL_SUCCESS) { + ERR("calendar_svc_get() Failed(%d)", ret); + return; + } + + printf("%s(%s)\n\t acc = %d\n\t type = %d\n", + calendar_svc_struct_get_str(calendar, CAL_TABLE_TXT_NAME), + calendar_svc_struct_get_str(calendar, CAL_TABLE_TXT_DESCRIPTION), + calendar_svc_struct_get_int(calendar, CAL_TABLE_INT_ACCOUNT_ID), + calendar_svc_struct_get_int(calendar, CAL_TABLE_INT_STORE_TYPE)); + + calendar_svc_struct_free(&calendar); +} + +int main(int argc, char **argv) +{ + int ret; + + calendar_svc_connect(); + + ret = insert_calendar1(); + DBG("get_calendar"); + get_calendar(ret); + + ret = insert_calendar2(); + DBG("get_calendar"); + get_calendar(ret); + + calendar_svc_close(); + + return 0; +} + + diff --git a/test/schedule-test.c b/test/schedule-test.c new file mode 100755 index 0000000..660de1c --- /dev/null +++ b/test/schedule-test.c @@ -0,0 +1,155 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include + +#include "test-log.h" + +static inline int insert_test() +{ + int ret; + cal_struct *event = NULL; + cal_value *attendee1 = NULL, *attendee2 = NULL; + cal_value *alarm_info1 = NULL, *alarm_info2 = NULL; + + GList *attendee_list=NULL; + GList *alarm_list = NULL; + + time_t cur_time = time(NULL)+240; + + event = calendar_svc_struct_new(CAL_STRUCT_SCHEDULE); + + calendar_svc_struct_set_str(event, CAL_VALUE_TXT_SUMMARY, "weekly meeting"); + calendar_svc_struct_set_str(event, CAL_VALUE_TXT_DESCRIPTION, "review : project status"); + calendar_svc_struct_set_str(event, CAL_VALUE_TXT_LOCATION, "meeting room #1"); + //calendar_svc_struct_set_int(event, CAL_VALUE_INT_SCH_CATEGORY, CAL_SCH_NONE); + calendar_svc_struct_set_int(event, CAL_VALUE_INT_REPEAT_TERM,1); + calendar_svc_struct_set_int(event, CAL_VALUE_INT_REPEAT_INTERVAL,3); + calendar_svc_struct_set_time(event, CAL_VALUE_GMT_START_DATE_TIME,CAL_TZ_FLAG_GMT,cur_time); + calendar_svc_struct_set_time(event, CAL_VALUE_GMT_END_DATE_TIME,CAL_TZ_FLAG_GMT,cur_time+(60*60)); + calendar_svc_struct_set_time(event, CAL_VALUE_GMT_REPEAT_END_DATE,CAL_TZ_FLAG_GMT,cur_time+(60*60*24*7)); + + //location + calendar_svc_struct_set_str(event,CAL_VALUE_TXT_LOCATION,"location field"); + calendar_svc_struct_set_str(event,CAL_VALUE_TXT_LOCATION_SUMMARY,"location field"); + calendar_svc_struct_set_str(event,CAL_VALUE_TXT_TZ_NAME,"Asia/Seoul"); + calendar_svc_struct_set_double(event,CAL_VALUE_DBL_LATITUDE,0.1); + calendar_svc_struct_set_double(event,CAL_VALUE_DBL_LONGITUDE,0.2); + + calendar_svc_struct_set_int(event, CAL_VALUE_INT_SYNC_STATUS,1); + + attendee1 = calendar_svc_value_new(CAL_VALUE_LST_ATTENDEE_LIST); + if(attendee1) { + calendar_svc_value_set_str(attendee1, CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME, "heungjae jeong"); + calendar_svc_value_set_str(attendee1, CAL_VALUE_TXT_ATTENDEE_DETAIL_EMAIL, "id@domain.com"); + calendar_svc_value_set_int(attendee1, CAL_VALUE_INT_ATTENDEE_DETAIL_STATUS, 1); + calendar_svc_value_set_int(attendee1, CAL_VALUE_INT_ATTENDEE_DETAIL_CT_INDEX, 1); + attendee_list = g_list_append(attendee_list, attendee1); + } + + attendee2 = calendar_svc_value_new(CAL_VALUE_LST_ATTENDEE_LIST); + if(attendee2) { + calendar_svc_value_set_str(attendee2, CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME, "boncheol gu"); + calendar_svc_value_set_str(attendee2, CAL_VALUE_TXT_ATTENDEE_DETAIL_EMAIL, "id@domain.com"); + calendar_svc_value_set_int(attendee2, CAL_VALUE_INT_ATTENDEE_DETAIL_STATUS, 0); + calendar_svc_value_set_int(attendee2, CAL_VALUE_INT_ATTENDEE_DETAIL_CT_INDEX, 2); + attendee_list = g_list_append(attendee_list, attendee2); + } + + ret = calendar_svc_struct_store_list(event, CAL_VALUE_LST_ATTENDEE_LIST, attendee_list); + + + alarm_info1 = calendar_svc_value_new(CAL_VALUE_LST_ALARM); + if(alarm_info1) { + calendar_svc_value_set_int(alarm_info1, CAL_VALUE_INT_ALARMS_TICK, 1); + calendar_svc_value_set_int(alarm_info1, CAL_VALUE_INT_ALARMS_TICK_UNIT,CAL_SCH_TIME_UNIT_MIN); + alarm_list = g_list_append(alarm_list, alarm_info1); + } + + alarm_info2 = calendar_svc_value_new(CAL_VALUE_LST_ALARM); + if(alarm_info2) { + calendar_svc_value_set_int(alarm_info2, CAL_VALUE_INT_ALARMS_TICK, 2); + calendar_svc_value_set_int(alarm_info2, CAL_VALUE_INT_ALARMS_TICK_UNIT, CAL_SCH_TIME_UNIT_MIN); + } + alarm_list = g_list_append(alarm_list, alarm_info2); + + ret = calendar_svc_struct_store_list(event, CAL_VALUE_LST_ALARM, alarm_list); + + ret = calendar_svc_insert(event); + calendar_svc_struct_free(&event); + + if (ret < CAL_SUCCESS) { + ERR("calendar_svc_insert() Failed(%d)", ret); + return -1; + } else { + DBG("calendar_svc_insert() return %d", ret); + return ret; + } +} + +static inline void get_event(int index) +{ + cal_struct *event = NULL; + int ct_value = 0; + int repeat_term = 0; + int interval = 0; + time_t r_end_date_time = 0; + GList *attendee_list=NULL; + time_t cur_time = time(NULL)+240; + + event = NULL; + calendar_svc_get(CAL_STRUCT_SCHEDULE, index, NULL, &event); + repeat_term = calendar_svc_struct_get_int(event, CAL_VALUE_INT_REPEAT_TERM); + interval = calendar_svc_struct_get_int(event, CAL_VALUE_INT_REPEAT_INTERVAL); + r_end_date_time = calendar_svc_struct_get_time(event, CAL_VALUE_GMT_REPEAT_END_DATE,CAL_TZ_FLAG_LOCAL); + + //location + char *location = calendar_svc_struct_get_str(event,CAL_VALUE_TXT_LOCATION); + char *location_summary = calendar_svc_struct_get_str(event,CAL_VALUE_TXT_LOCATION_SUMMARY); + double latitude = calendar_svc_struct_get_double(event,CAL_VALUE_DBL_LATITUDE); + double longitude = calendar_svc_struct_get_double(event,CAL_VALUE_DBL_LONGITUDE); + int sync_status = calendar_svc_struct_get_int(event, CAL_VALUE_INT_SYNC_STATUS); + char *tz_name = calendar_svc_struct_get_str(event,CAL_VALUE_TXT_TZ_NAME); + + DBG("tz_name:Asia/Seoul = %s",tz_name); + DBG("location: %s,%s,%s, %lf, %lf, %d",location,location_summary,tz_name,latitude,longitude,sync_status); + DBG("curtime:%ld, event repeat_term(%d,%d,%ld)",cur_time,repeat_term,interval,r_end_date_time); + + attendee_list = NULL; + calendar_svc_struct_get_list(event,CAL_VALUE_LST_ATTENDEE_LIST,&attendee_list); + ct_value = calendar_svc_value_get_int(attendee_list->data,CAL_VALUE_INT_ATTENDEE_DETAIL_CT_INDEX); + + calendar_svc_struct_free(&event); +} + +int main(int argc, char **argv) +{ + int ret; + + calendar_svc_connect(); + + ret = insert_test(); + if (0 < ret) + get_event(ret); + + calendar_svc_close(); + + return 0; +} + diff --git a/test/test-log.h b/test/test-log.h new file mode 100755 index 0000000..8e3acc3 --- /dev/null +++ b/test/test-log.h @@ -0,0 +1,36 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __TEST_LOG_H__ +#define __TEST_LOG_H__ + +#include +#include + +#define PRT(prio, fmt, arg...) \ + do { fprintf((prio?stderr:stdout),fmt"\n", ##arg); } while (0) +#define INFO(fmt, arg...) PRT(0, fmt, ##arg) +#define ERR(fmt, arg...) PRT(1,"\x1b[101;38m[ERROR]\x1b[0m%s :" fmt, __FUNCTION__, ##arg) +#define DBG(fmt, arg...) \ + do { \ + printf("\x1b[105;37m[%s]\x1b[0m" fmt"\n", __FUNCTION__, ##arg); \ + } while (0) + +#define TEST_FN_START DBG("[FUNC_START]") + +#endif /* __TEST_LOG_H__ */ diff --git a/test/timetest.c b/test/timetest.c new file mode 100755 index 0000000..f1cb97d --- /dev/null +++ b/test/timetest.c @@ -0,0 +1,143 @@ +/* + * Calendar Service + * + * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include +#include +#include +#include "timetest.h" +#include "test-log.h" + +FILE *outfp; +double correction; + +double set_start_time(void) +{ + // TEST_FN_START; + + struct timeval tv; + double curtime; + + gettimeofday(&tv, NULL); + curtime = tv.tv_sec * 1000 + (double)tv.tv_usec/1000; + return curtime; +} + +double exec_time(double start) +{ + // TEST_FN_START; + + double end = set_start_time(); + return (end - start - correction); +} + +int init_time(void) +{ + // TEST_FN_START; + + double temp_t; + temp_t = set_start_time(); + correction = exec_time(temp_t); + + return 0; +} + +int print_time(char *prn_args, double time) +{ + TEST_FN_START; + +#ifdef USE_STD_OUT + printf("%200s =\t", prn_args); + printf("%f \n", time); +#else + fprintf(outfp, "%.50s\t", prn_args); + fprintf(outfp, "%f \n", time); +#endif + + return 0; +} + + +int print_argument(char *prn_args) +{ + TEST_FN_START; + +#ifdef USE_STD_OUT + printf("%s", prn_args); +#else + fprintf(outfp, "%s\n", prn_args); +#endif + + return 0; +} + + + +int print_milestone(char *prn_args, int level) +{ + TEST_FN_START; + int i; + + if (level > 1) { + for (i=0;i